This error isn't too surprising if the MessageHeader.class doesn't have an XmlRootElement annotation on it with the proper name/namespace. Headers have to be defined as root elements. Alternatively, passing the generated ObjectFactory to the JAXBDataBinding instead of the MessageHeader.class may also work.
Dan On Tuesday, May 17, 2011 7:24:33 AM Michael Täschner wrote: > Hi again, > > I tried with a basic impl of the HeaderProcessor but fails with following > exception. > > Register processor: > // create new ServerFactoryBean > final JaxWsServerFactoryBean svrFactory = new > JaxWsServerFactoryBean(); > svrFactory.setServiceClass(serviceInterface); > svrFactory.setAddress(contextPath); > svrFactory.setServiceBean(endpoint); > > // create the server and save the reference > final Server server = svrFactory.create(); > > ... > // add our soap header interceptor > HeaderProcessor processor = new HeaderProcessor() { > > @Override > public String getNamespace() { > return "http://www.lhsystems.com/gsp/commonSchema"; > } > > @Override > public InterceptorProvider getInterceptorProvider() { > return svrFactory.getBus(); > } > > @Override > public DataBinding getDataBinding() { > try { > return new JAXBDataBinding(MessageHeader.class); > } catch (JAXBException e) { > return null; > } > } > }; > > > svrFactory.getBus().getExtension(HeaderManager.class).registerHeaderProcess > or(processor); server.getEndpoint().getInInterceptors().add(new > ReadHeadersInterceptor(svrFactory.getBus())); > server.getEndpoint().getInInterceptors().add(new > ReadSOAPHeaderInInterceptor()); > > Exception in ReadHeadersInterceptor: > 17.05.2011 11:16:55 org.apache.cxf.phase.PhaseInterceptorChain doIntercept > WARNUNG: Interceptor has thrown exception, unwinding now > org.apache.cxf.interceptor.Fault: Unmarshalling Error: unexpected element > (uri:"http://www.lhsystems.com/gsp/commonSchema", local:"messageHeader"). > Expected elements are (none) > at > org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:6 > 28) at > org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:5 > 30) at > org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:114) > at > org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:53) > at > org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessag > e(ReadHeadersInterceptor.java:161) at > org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor.handleMessag > e(ReadHeadersInterceptor.java:58) at > org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChai > n.java:236) at > org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationO > bserver.java:104) at > org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestinati > on.java:99) at > org.apache.cxf.transport.servlet.ServletController.invokeDestination(Servle > tController.java:452) at > org.apache.cxf.transport.servlet.ServletController.invoke(ServletController > .java:196) at > org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServl > et.java:220) at > org.apache.cxf.transport.servlet.AbstractCXFServlet.doPost(AbstractCXFServl > et.java:153) at > javax.servlet.http.HttpServlet.service(HttpServlet.java:727) at > org.apache.cxf.transport.servlet.AbstractCXFServlet.service(AbstractCXFServ > let.java:211) at > org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) > at > org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390) > at > org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216) > at > org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182) > at > org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765) > at > org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:440) > at > org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCol > lection.java:230) at > org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:1 > 14) at > org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152) > at org.mortbay.jetty.Server.handle(Server.java:326) > at > org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542) > at > org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java > :943) at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756) at > org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212) at > org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404) at > org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410 > ) at > org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java: > 451) Caused by: javax.xml.bind.UnmarshalException: unexpected element > (uri:" http://www.lhsystems.com/gsp/commonSchema", local:"messageHeader"). > Expected elements are (none) > at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.hand > leEvent(UnmarshallingContext.java:631) at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader > .java:236) at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader > .java:231) at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedCh > ildElement(Loader.java:105) at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$Defa > ultRootLoader.childElement(UnmarshallingContext.java:1038) at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._sta > rtElement(UnmarshallingContext.java:467) at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.star > tElement(UnmarshallingContext.java:448) at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.start > Element(InterningXmlVisitor.java:60) at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement > (SAXConnector.java:137) at > com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:228 > ) at > com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:111) > at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarsha > l0(UnmarshallerImpl.java:303) at > com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarsha > l(UnmarshallerImpl.java:286) at > org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:6 > 07) ... 31 more > > I am quite confused with the message "Expected elements are (none)" > > Thanks again, > Michael > > Am 17. Mai 2011 13:01 schrieb Michael Täschner <m.taesch...@googlemail.com>: > > Hi Daniel, > > > > I followed Svens and your suggestion and removed the SAAJ stuff. My > > ReadSOAPHeaderInInterceptor now looks as follows: > > > > > > public class ReadSOAPHeaderInInterceptor extends AbstractSoapInterceptor > > { > > > > private final static Logger log = > > > > LoggerFactory.getLogger(ReadSOAPHeaderInInterceptor.class); > > // private QName messageHeader = new QName("messageHeader"); > > > > public ReadSOAPHeaderInInterceptor() { > > > > super(Phase.POST_LOGICAL); > > addAfter(ReadHeadersInterceptor.class.getName()); > > > > } > > > > @Override > > public void handleMessage(final SoapMessage message) throws Fault { > > > > log.info("handleMessage started"); > > > > > > for (Header header :message.getHeaders()) { > > > > log.info("name: "+header.getName().toString()); > > log.info("binding: "+header.getDataBinding()); > > log.info("object: "+header.getObject()); > > > > } > > > > log.info("handleMessage done"); > > > > } > > > > } > > > > The "messageHeader" header is found yet binding and object are always > > null. Additionally I found your suggestion from another soap header > > related mail where you point to registering a HeaderProcessor - I would > > use that approach but don't know how to implement the > > InterceptorProvider > > getInterceptorProvider(); method in this case. Can you give me some more > > help with this ? Do I need to register more interceptors than the > > ReadHeadersInterceptor ?? > > > > Not right now... My quick 30 second tutorial would be: > >> In your setup code, you would need to *register* an instance of > >> HeaderProcessor with the HeaderManager extension found on the Bus: > >> bus.getExtension(HeaderManager.class).*registerHeaderProcessor*(processo > >> r); > >> > >> > >> Your header processor would hold an instance of JAXBDataBinding > >> configured with the classes your namespace will processes. > >> > >> Thus, when the ReadHeadersInterceptor encounters headers in your > >> namespace, it will grab the *DataBinding* and deserialize it to the > >> correct object. That said, it deserializes the entire header element. > >> You would need a JAXB class for the qo:header type which has a "foo" > >> field of the foo type. > > > > Thanks and Kind Regards, > > Michael > > > > Am 16. Mai 2011 21:12 schrieb Daniel Kulp <dk...@apache.org>: > > > > On Monday, May 16, 2011 9:26:36 AM Michael Täschner wrote: > >> > Hi CXF-Users, > >> > > >> > can anybody help me figuring out how to read my client set SOAP header > >> > >> on > >> > >> > server side via an interceptor or give me an idea if my approach is > >> > incorrect ? > >> > >> As Sven mentioned, if your interceptor is a <SoapMessage> kind, the > >> SoapMessage passed to it would have a getHeaders call that is preferred > >> over > >> using the SAAJ stuff as the SAAJ stuff would break the streaming. > >> > >> The issue with your code MAY be: > >> if ("messageHeader".equals(node.getNodeName())) { > >> > >> Since CXF uses the Namespace aware parsers, you may need: > >> if ("messageHeader".equals(((Element)node).getLocalName())) { > >> > >> or similar ad getNodeName may be returning the fully qualified name. > >> > >> Dan > >> > >> > Thanks and Regards, > >> > Michael > >> > > >> > Am 13. Mai 2011 12:08 schrieb Michael Täschner < > >> > >> m.taesch...@googlemail.com>: > >> > > Hi again, > >> > > > >> > > can anyone give me a hint how to access the SOAP Header (complexType > >> > > "messageHeader") from the request via an interceptor ? > >> > > > >> > > Thanks and Regards, > >> > > Michael > >> > > > >> > > Am 10. Mai 2011 17:17 schrieb Michael Täschner > >> > > <m.taesch...@googlemail.com > >> > > > >> > > > >> > > Hi, > >> > > > >> > >> I have been trying to handle SOAP headers outside of functional > >> > >> operations, meaning I do not use @WebParam to separate business > >> > >> concern > >> > >> > >> from context and/or authorization information. The header type is > >> > >> added > >> > >> > >> to the SEI via @XmlSeeAlso and using the jaxb binding I can set the > >> > >> header on the client side (verified by looking at tcpmon > >> > >> requests/responses) > >> > >> > >> > >> Client: > >> > >> CalculatorService service = new CalculatorService(endpoint); > >> > >> > >> > >> final Header header = new Header(new QName("messageHeader"), > >> > >> > >> > >> messageHeader, new JAXBDataBinding(MessageHeader.class)); > >> > >> > >> > >> final List<Header> headers = new ArrayList<Header>(); > >> > >> headers.add(header); > >> > >> > >> > >> Calculator calculator = service.getCalculatorPort(); > >> > >> ((BindingProvider)calculator).getRequestContext().put(Header.HEADER_LIST > >> > >> > >> , headers); > >> > >> > >> > >> > >> > >> On the server side the CXF server is created manually using > >> > >> JaxWsServerFactoryBean and I register my interceptor implementation > >> > >> ReadSOAPHeaderInInterceptor. Unfortunately, whatever approach I > >> > >> chose, I > >> > >> > >> can retrieve the "messageHeader" element from the message but the > >> > >> properties are always null (values). Could somebody give me a hint > >> > >> of what I am missing ? > >> > >> > >> > >> CXF Server creation: > >> > >> final JaxWsServerFactoryBean svrFactory = new > >> > >> JaxWsServerFactoryBean(); > >> > >> > >> > >> svrFactory.setServiceClass(serviceInterface); > >> > >> svrFactory.setAddress(contextPath); > >> > >> svrFactory.setServiceBean(endpoint); > >> > >> > >> > >> // create the server and save the reference > >> > >> final Server server = svrFactory.create(); > >> > >> > >> > >> // add our soap header interceptor > >> > >> server.getEndpoint().getInInterceptors().add(new > >> > >> SAAJInInterceptor()); > >> > >> > >> server.getEndpoint().getInInterceptors().add(new > >> > >> > >> > >> ReadSOAPHeaderInInterceptor()); > >> > >> > >> > >> Interceptor impl: > >> > >> public class ReadSOAPHeaderInInterceptor extends > >> > >> AbstractSoapInterceptor > >> > >> > >> { > >> > >> > >> > >> private final static Logger log = > >> > >> > >> > >> LoggerFactory.getLogger(ReadSOAPHeaderInInterceptor.class); > >> > >> > >> > >> private QName messageHeader = new QName("messageHeader"); > >> > >> private SAAJInInterceptor saajIn = new SAAJInInterceptor(); > >> > >> > >> > >> public ReadSOAPHeaderInInterceptor() { > >> > >> > >> > >> super(Phase.USER_PROTOCOL); > >> > >> addAfter(ReadHeadersInterceptor.class.getName()); > >> > >> addAfter(SAAJInInterceptor.class.getName()); > >> > >> > >> > >> } > >> > >> > >> > >> @Override > >> > >> public void handleMessage(final SoapMessage message) throws > >> > >> Fault > >> > >> { > >> > >> > >> log.info("handleMessage started"); > >> > >> > >> > >> Header header = message.getHeader(messageHeader); > >> > >> > >> > >> if (null == header) { > >> > >> > >> > >> throw new SoapFault("SOAP Header MessageHeader is > >> > >> missing", > >> > >> > >> new QName("missingMessageHeader")); > >> > >> > >> > >> } > >> > >> log.info("header object: " + header.getObject()); > >> > >> > >> > >> SOAPMessage doc = message.getContent(SOAPMessage.class); > >> > >> if (doc == null) { > >> > >> > >> > >> log.debug("SOAPMessage not set, handle with own saaj > >> > >> > >> > >> interceptor"); > >> > >> > >> > >> saajIn.handleMessage(message); > >> > >> doc = message.getContent(SOAPMessage.class); > >> > >> > >> > >> } > >> > >> SOAPHeader headers = null; > >> > >> try { > >> > >> > >> > >> headers = doc.getSOAPHeader(); > >> > >> > >> > >> } catch (SOAPException e) { > >> > >> > >> > >> e.printStackTrace(); > >> > >> > >> > >> } > >> > >> > >> > >> for (Iterator<SOAPElement> nodeIter = > >> > >> headers.getChildElements(); > >> > >> > >> > >> nodeIter.hasNext();) { > >> > >> > >> > >> SOAPElement node = nodeIter.next(); > >> > >> log.info(String.format("node %s with value %s", > >> > >> > >> > >> node.getNodeName(), node.getNodeValue())); > >> > >> > >> > >> if ("messageHeader".equals(node.getNodeName())) { > >> > >> > >> > >> log.info("found messageHeader node"); > >> > >> MessageHeader messageHeader = new MessageHeader(); > >> > >> for (int i = 0 ; i < > >> > >> node.getChildNodes().getLength(); > >> > >> > >> i++) { > >> > >> > >> > >> SOAPElement property = > >> > >> > >> > >> (SOAPElement)node.getChildNodes().item(i); > >> > >> > >> > >> log.info("property: "+property.getNodeName()); > >> > >> > >> > >> if("session".equals(property.getNodeName())) { > >> > >> messageHeader.setSession(property.getNodeValue() > >> > >> > >> ); > >> > >> > >> > >> } else if > >> > >> ("clientIP".equals(property.getNodeName())) > >> > >> > >> > >> { > >> > >> > >> > >> messageHeader.setClientIP(property.getNodeValue()); > >> > >> > >> > >> } else if > >> > >> ("clientID".equals(property.getNodeName())) > >> > >> > >> > >> { > >> > >> > >> > >> messageHeader.setClientID(property.getNodeValue()); > >> > >> > >> > >> } else if > >> > >> ("requestID".equals(property.getNodeName())) > >> > >> > >> > >> { > >> > >> > >> > >> try { > >> > >> messageHeader.setRequestID(Integer.parseInt(property.getNodeValue())); > >> > >> > >> } catch (NumberFormatException nfe) { > >> > >> > >> > >> log.warn("requestId is not valid: > >> > >> "+property.getNodeValue()); > >> > >> > >> > >> messageHeader.setRequestID(0); > >> > >> > >> > >> } > >> > >> > >> > >> } > >> > >> > >> > >> } > >> > >> > >> > >> RequestContext.getInstance().setMessageHeader(messageHeader); > >> > >> > >> > >> break; > >> > >> > >> > >> } > >> > >> > >> > >> } > >> > >> > >> > >> } > >> > >> > >> > >> } > >> > >> > >> > >> Thanks and Regards, > >> > >> > >> > >> Michael > >> > >> -- > >> Daniel Kulp > >> dk...@apache.org > >> http://dankulp.com/blog > >> Talend - http://www.talend.com -- Daniel Kulp dk...@apache.org http://dankulp.com/blog Talend - http://www.talend.com