Java Reference
In-Depth Information
To implement a
WriterInterceptor
, we must define an
aroundWriteTo()
method. We
start off in this method by creating a
java.security.MessageDigest
. We'll use this class
to create an MD5 hash of the entity we're marshalling.
ByteArrayOutputStream buffer
=
new
new
ByteArrayOutputStream
();
DigestOutputStream digestStream
=
new
new
DigestOutputStream
(
buffer
,
digest
);
OutputStream old
=
context
.
getOutputStream
();
context
.
setOutputStream
(
digestStream
);
Next we create a
java.io.ByteArrayOutputStream
and wrap it with a
java.security.DigestOutputStream
. The MD5 hash is created from the marshalled bytes
of the entity. We need to buffer this marshalling in memory, as we need to set the
Content-
MD5
before the entity is sent across the wire. We override the
OutputStream
of the
Contain-
erRequestContext
so that the
MessageBodyWriter
that performs the marshalling uses the
DigestOutputStream
.
try
try
{
context
.
proceed
();
byte
byte
[]
hash
=
digest
.
digest
();
String encodedHash
=
Base64
.
encodeBytes
(
hash
);
context
.
getHeaders
().
putSingle
(
"Content-MD5"
,
encodedHash
);
Next,
context.proceed()
is invoked. This continues with the interceptor chain and until
the underlying
MessageBodyWriter
is invoked. After
proceed()
finishes, we obtain the
hash from the
MessageDigest
and Base-64-encode it using a RESTEasy utility class. We
then set the
Content-MD5
header value with this encoded string.
byte
byte
[]
content
=
buffer
.
toByteArray
();
old
.
write
(
content
);
}
After the header is set, we write the buffered content to the real
OutputStream
.
finally
finally
{
context
.
setOutputStream
(
old
);
}
}
}
Finally, if you override the context's
OutputStream
it is always best practice to revert it after
you finish intercepting. We do this in the
finally
block.