Hi

You can try to write a code similar to the one in LoggingOutInterceptor
:

http://svn.apache.org/repos/asf/cxf/trunk/rt/core/src/main/java/org/apac
he/cxf/interceptor/LoggingOutInterceptor.java

JAXBElementWriter can also write into a custom XMLStreamWriter, so may
be another option is to register a custom writer (say from response
handler) which will delegate the events to the writer wrapping the
response output stream (created like this
StaxUtils.createXMLStreamWriter(os)), but also copy the events into
(CXF) CachingXmlEventWriter. And then when the end of document has been
signaled, replay the events like this :

XMLStreamWriter writer = StaxUtils.createXMLStreamWriter(new
ByteArrayOutputStream());
for (XMLEvent event : cache.getEvents()) {
   StaxUtils.writeEvent(event, origWriter);
}
Let me know please if either of these options works  for you 

Hope it helps, Sergey

-----Original Message-----
From: Vitaly Peressada [mailto:[email protected]] 
Sent: 02 February 2010 20:46
To: [email protected]
Subject: RE: Capture Serialized Response

David,

I do have a need for this feature - I want to implement request/response
capture. On the request side I did figure out how to get http request

public static String readCxfMsg(Message msg) {
                String content = null;
                InputStream is = null;
                ByteArrayInputStream bais1 = null;
                ByteArrayInputStream bais2 = null;
                
                try {
                        is = msg.getContent(InputStream.class);
                        byte[] data = IOUtils.inputStreamToBytes(is);
                        bais1 = new ByteArrayInputStream(data);
                        content = FormUtils.readBody(bais1);
                        
                        bais2 = new ByteArrayInputStream(data);
                        msg.setContent(InputStream.class, bais2);       
                        
                } catch (Exception e) {
                        throw new RuntimeException(e);
                } 
                finally {
                        try {
                                if (is != null) {
                                        is.close();
                                }
                                if (bais1 != null) {
                                        bais1.close();
                                }
                                // We will not close bais2. Supposedly
CXF will read it and close it.
                        }
                        catch (Exception e) {
                                throw new RuntimeException(e);
                        }
                }
                
                return content;
}

Could not do the same for the response. For now, since majority of our
responses are application/xml I use JAXB to serialize xml myself but it
would be nice to plug in into CXF after it does serialization and simply
read OutputStream of http response.




-----Original Message-----
From: KARR, DAVID (ATTCINW) [mailto:[email protected]] 
Sent: Tuesday, February 02, 2010 3:16 PM
To: [email protected]
Subject: RE: Capture Serialized Response

> -----Original Message-----
> From: Vitaly Peressada [mailto:[email protected]]
> Sent: Tuesday, February 02, 2010 11:29 AM
> To: [email protected]
> Subject: Capture Serialized Response
> 
> I am using JAX-RS and want to capture serialized HTTP output after CXF
> serializes response as per configured content-type. I tried my own
> ResponseHandler but could not get the hold on output stream. I think
> serialization happens later in CXF chain.

Are you doing this for testing sake, or do you really have an
application need for this?

If the latter, I suppose you could implement a servlet filter, although
Sergey or others may have better ideas.

If you're doing this for testing, this is something I had to figure out
a while ago (and you can find some more details by searching this list
for my question about this ("How can I make WebClient in test return raw
XML or JSON?").  This uses an embedded Jetty instance.

I use something like this in the test class:
---------------------
    @BeforeClass
    public static void startServer() {
        JAXRSServerFactoryBean  sf  = new JAXRSServerFactoryBean();
        sf.setServiceBeans(catalogContentController);
        sf.getInInterceptors().add(new LoggingInInterceptor());
        sf.getOutInterceptors().add(new LoggingOutInterceptor());
        sf.setProvider(new JacksonJsonProvider());
        
        sf.setAddress(BASE_SERVICE_URI);
        
        Map<Object, Object> mappings = new HashMap<Object, Object>();
        mappings.put("xml", "application/xml");
        mappings.put("json", "application/json");
        sf.setExtensionMappings(mappings);
        
        JacksonInit jacksonInit = new JacksonInit();
        ObjectMapper    objectMapper    = new ObjectMapper();
        jacksonInit.setObjectMapper(objectMapper);
        jacksonInit.setAnnotationIntrospector(new
AnnotationIntrospector.Pair(new JacksonAnnotationIntrospector(),
 
new JaxbAnnotationIntrospector()));
        jacksonInit.init();
        
        sf.create();
    }
-----------------

Then my individual tests can do something like this:
------------------------
        WebClient   client  = WebClient.create(BASE_SERVICE_URI);
        client.path("/catalog/catalog/" + id);
        
        catalog = client.get(Catalog.class);
        assertEquals(id, catalog.getId());
        
        Response    response    = client.get();
        System.out.println("response[" + response + "]");
-----------------
(Sergey's response to my question about this suggested doing
"client.get(Response.class)", but this appears to do the same thing.)

The Response object gives you a stream to read from and HTTP headers.


Reply via email to