Actually, there is no JAXWS or JAXB in this case, the server processes XML documents dynamically.
Gary > -----Original Message----- > From: Sergey Beryozkin [mailto:[email protected]] > Sent: Friday, December 18, 2009 02:32 > To: [email protected] > Cc: Lee Breisacher; Nikolay Glazyrin > Subject: Re: Inflexible fault interceptor chain? > > Hi, > > I'm presuming you use JAXWS. > Please see a couple of comments inline prefixed with S.B, perhaps they > migth help > > cheers, Sergey > > Hi All: > > I need to apply an XSL transformation to messages coming out of CXF > (our users configure what the XSL looks like.) For a normal > (successful) message, I have an interceptor (during Phase.PRE_MARSHAL) > that uses the DOM aspect of a message. That works great. BTW, > I get to the DOM like this: > > Node node = (Node) message.getContent(List.class).get(0); > > That seems brittle, is there a safer way to get to an aspect of the > message I can feed to javax.xml.transform? > > >S.B. Perhaps you can inject an out interceptor before the response > object (which is a JAXB Bean) is wrapped into DOM ? And then > use JAXBContext to marshal into an XSLT engine handler and then abort > the chain ? JAXBDatabinding keeps the map of existing > JAXBContexts but I'm not sure how exactly they can be retrieved... > > The real issue comes with fault messages because the fault chain uses > an > XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/ > XMLStreamWriter.html>. The fault chain looks like this: > > > S.B : is it possible to catch a Fault before early, and use JAXB to > XSLT path again, perhaps by wrapping a Fault in a JAXBContext > > ? > > > Chain org.apache.cxf.phase.phaseinterceptorch...@3015b303. Current > flow: > setup [ServerPolicyOutFaultInterceptor] > prepare-send [MessageSenderInterceptor, Soap11FaultOutInterceptor] > pre-stream [LoggingOutInterceptor, XmlDeclOutInterceptor*, > StaxOutInterceptor] > pre-protocol [WebFaultOutInterceptor, SOAPHandlerFaultOutInterceptor] > write [SoapOutInterceptor] > pre-marshal [LogicalHandlerFaultOutInterceptor] > marshal [Soap11FaultOutInterceptorInternal] > pre-stream-ending [StaxOutEndingInterceptor, > TransformOutFaultInterceptor*] > prepare-send-ending [MessageSenderEndingInterceptor] > > FYI, the interceptors marked with * are our own: > > * XmlDeclOutInterceptor forces an XML declaration to be > written. > > * TransformOutFaultInterceptor is where I thought I could > transform the fault XML message. > > The > XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/ > XMLStreamWriter.html> looks like this: > > [StreamWriter: class com.ctc.wstx.sw.SimpleNsStreamWriter, underlying > outputter: > com.ctc.wstx.sw.isolatin1xmlwri...@1125cf44<mailto:com.ctc.wstx.sw.ISOL > atin1xmlwri...@1125cf44> > > The com.ctc.wstx.sw.ISOLatin1XmlWriter wraps a > org.apache.cxf.io.CachedOutputStream, which in turns wraps: > > * currentStream - LoadingByteArrayOutputStream > > * flowThroughStream - > AbstractHTTPDestination$WrappedOutputStream > > All of this to say that when the chain's interceptors are working with > the message's > XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/ > XMLStreamWriter.html>, the bytes are cached and written to > the wire. It is not possible to catch the fault XML message and change > it. > > The only thing I've come up with but not implemented yet would be to > insert an interceptor before the XML declaration is written and > put the > XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/ > XMLStreamWriter.html> into a temp spot in the message > content map, then put a new > XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/ > XMLStreamWriter.html> on a byte > array in its place. A pre-stream-ending interceptor can take those > bytes, apply XSL to them and then write them to the original > XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/ > XMLStreamWriter.html>, before putting the original > XMLStreamWriter<http://java.sun.com/javase/6/docs/api/javax/xml/stream/ > XMLStreamWriter.html> back in it original slot in the message > content map. > > That seems like big old hack. > > Any ideas on a cleaner solution? > > Thank you, > Gary Gregory > Seagull Software > [email protected] > www.seagullsoftware.com >
