Yes, that's possible. You need to decorate the response with help of HttpServletResponseWrapper
wherein you replace the ServletOutputStream
with a custom implementation which writes the bytes to both the MD5 digest and the "original" outputstream. Finally provide an accessor to obtain the final MD5 sum.
Update I just for fun played a bit round it, here's a kickoff example:
The response wrapper:
public class MD5ServletResponse extends HttpServletResponseWrapper {
private final MD5ServletOutputStream output;
private final PrintWriter writer;
public MD5ServletResponse(HttpServletResponse response) throws IOException {
super(response);
output = new MD5ServletOutputStream(response.getOutputStream());
writer = new PrintWriter(output, true);
}
public PrintWriter getWriter() throws IOException {
return writer;
}
public ServletOutputStream getOutputStream() throws IOException {
return output;
}
public byte[] getHash() {
return output.getHash();
}
}
The MD5 outputstream:
public class MD5ServletOutputStream extends ServletOutputStream {
private final ServletOutputStream output;
private final MessageDigest md5;
{
try {
md5 = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
throw new ExceptionInInitializerError(e);
}
}
public MD5ServletOutputStream(ServletOutputStream output) {
this.output = output;
}
public void write(int i) throws IOException {
byte[] b = { (byte) i };
md5.update(b);
output.write(b, 0, 1);
}
public byte[] getHash() {
return md5.digest();
}
}
How to use it:
// Wrap original response with it:
MD5ServletResponse md5response = new MD5ServletResponse(response);
// Now just use md5response instead or response, e.g.:
dispatcher.handle(request, md5response);
// Then get the hash, e.g.:
byte[] hash = md5response.getHash();
StringBuilder hashAsHexString = new StringBuilder(hash.length * 2);
for (byte b : hash) {
hashAsHexString.append(String.format("%02x", b));
}
System.out.println(hashAsHexString); // Example af28cb895a479397f12083d1419d34e7.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…