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

Reply via email to