users@glassfish.java.net

Re: Access to raw XML in Jersey

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Mon, 20 Jul 2009 12:55:46 +0200

On Jul 20, 2009, at 12:26 PM, glassfish_at_javadesktop.org wrote:

> Hi,
>
> I am trying to add an XMLDSIG to every reply that a jersey REST
> service creates.
>
> My problem is that I have to get access to the raw XML created by
> the REST service in order to add the xml dsig XML element to the
> reply.
>
> How do I access the raw XML created by a jersey REST service?
>
> I have been looking at
> com.sun.jersey.spi.container.ContainerResponseFilter, but this only
> grants me access to the object being returned, not the raw xml.
>

You need to adapt ContainerResponseWriter [1], for example in your
filter:

     public ContainerResponse filter(ContainerRequest request,
ContainerResponse response) {
         response.setContainerResponseWriter(
                 new Adapter(response.getContainerResponseWriter()));
         return response;
     }

In your adapted ContainerResponseWriter you can then return an adapted
OutputStream. If you require the XML in some infoset form you will
need to re-parse the XML document.

See the LoggingFilter as an example:

   http://fisheye4.atlassian.com/browse/jersey/trunk/jersey/jersey-server/src/main/java/com/sun/jersey/api/container/filter/LoggingFilter.java?r=2168

Or alternatively you could buffer the response in a
ByteArrayOutputStream and so all the work in the
ContainerResponseWriter.finish method, for example:

     private final class BufferedAdapter implements
ContainerResponseWriter {
         private final ContainerResponseWriter crw;
         private ByteArrayOutputStream buffer;
         private ContainerResponse response;

         Adapter(ContainerResponseWriter crw) {
             this.crw = crw;
         }

         public OutputStream writeStatusAndHeaders(long contentLength,
ContainerResponse response) throws IOException {
            this.response = response;
            return out = new ByteArrayOutputStream();
         }

         public void finish() throws IOException {
             // May to check Content-Type of response
             // May need to additional HTTP response headers

             byte[] content = buffer.toByteArray();
             OutputSteam out = crw.writeStatusAndHeaders(-1, response)

             // Do security work here wrapping content and writing out
XMLDSIG stuff to out
         }
     }


If you want to avoid re-parsing the XML it is going to be a little
tricker. There are some possibilities with using JAXB/SAX but before i
go into that i would like to know if the above is sufficient for what
you require.

Paul.

[1] https://jersey.dev.java.net/nonav/apidocs/1.1.1-ea/jersey/com/sun/jersey/spi/container/ContainerResponseWriter.html