Thanks Sergey, I'll give it a shot. - Steve
On Mar 14, 2013, at 3:39 AM, Sergey Beryozkin <[email protected]> wrote: > Hi > On 14/03/13 02:59, Steve Karlovic wrote: >> Hello, >> I am using CXF for RESTful services. I would like to capture the time it >> takes to marshal the response separately from the time it takes to write the >> response and send it to the client. It seems like the JAXRSOutInterceptor is >> responsible for the marshalling. Immediately after marshalling it appears >> that the write occurs as well. Is there a way to have a method I write in my >> own class to be called as soon as the response is marshalled but before the >> data is sent? Is there another interceptor I should be looking at as well? >> We are using 2.6.1. > Assuming it is JAXB, what you can do is to register a custom XMLStreamWriter > which will calculate the time between writeStartDocument and > writeStartDocument. > > The custom writer can be registered from the out CXF interceptor or > ResponseHandler filter, like this: > > http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XmlStreamWriterProvider.java > > (see the two lines within the 'if' branch), on the trunk it is JAX-RS 2.0 > ContainerResponseFilter which does it, but the same two lines will work in > CXF 2.6.2 when done from the interceptor or ResponseHandler filter. > > The actual custom interceptor may look like this: > http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/XmlStreamWriterProvider.java > > except that all you will have to do is to override writeStartDocument & > writeEndDocument instead > > This will give you the time it takes to marshal. > > Catching the actual time when the response has been sent can be trickier I > guess. In JAX-RS 2.0 one can use > > http://jax-rs-spec.java.net/nonav/2.0-SNAPSHOT/apidocs/javax/ws/rs/container/CompletionCallback.html > > CXF will actually callback on it when the relevant async servlet callback is > called, so it can be really close. > > but that will work for the code using 2.0 AsyncResponse only, starting from > 2.7.x. > > I guess, what you can try to do is to replace an OutputStream on the message, > > OutputStream os = outMessage.getContent(OutputStream.class); > and wrap it with some filtered output stream that will catch when say flush() > is called, I'm not exactly sure how precise the data you can get with this > approach. Another option may be is to replace HttpServletResponse with a > wrapper (can be done from a servlet filter or even from CXF interceptor, it > is registered on the inbound message as "HTTP.RESPONSE"), and override its > ServletOutputStream, etc. > > HTH, Sergey > >> Thanks, >> Steve >
