Phil, Thank you. I very much appreciate your help. I replaced my previous use of AnnotationServiceFactory with MyServiceFactory that you kindly provided. MyServiceFactory extends JAXWSServiceFactory. The results are pretty encouraging.
For instance, the following request: <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"> <s:Header> <a:Action>urn:doEcho</a:Action> <a:To>http://www.lodh.com/arte/EchoService</a:To> <a:MessageID>urn:uuid:c87f9f62-79bb-4f93-bfd8-aaac26856cbf</a:MessageID> </s:Header> <s:Body> <doEcho xmlns="http://www.qos.ch/arte"> <inputStr>sd</inputStr> </doEcho> </s:Body> </s:Envelope> yields: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Header> <wsa:To xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:To> <wsa:Action xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">urn:doEchoResponse</wsa:Action> <wsa:RelatesTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing">urn:uuid:c87f9f62-79bb-4f93-bfd8-aaac26856cbf</wsa:RelatesTo> </soap:Header> <soap:Body> <doEchoResponse xmlns="http://www.qos.ch/arte"> <echoResult>You said: sd</echoResult> </doEchoResponse> </soap:Body> </soap:Envelope> However, if in the SOAP request, I replace <a:Action>urn:doEcho</a:Action> with: <a:Action s:mustUnderstand="1">urn:doEcho</a:Action> I get: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <soap:Fault> <faultcode>soap:MustUnderstand</faultcode> <faultstring>Header {Action}http://schemas.xmlsoap.org/ws/2004/08/addressing was not undertsood by the service.</faultstring> </soap:Fault> </soap:Body> </soap:Envelope> Looking at the logs: org.codehaus.xfire.fault.XFireFault: Header {Action}http://schemas.xmlsoap.org/ws/2004/08/addressing was not undertsood by the service. at org.codehaus.xfire.soap.handler.ValidateHeadersHandler.assertUnderstandsHeader(ValidateHeadersHandler.java:76) at org.codehaus.xfire.soap.handler.ValidateHeadersHandler.invoke(ValidateHeadersHandler.java:53) at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131) at org.codehaus.xfire.transport.DefaultEndpoint.onReceive(DefaultEndpoint.java:64) at org.codehaus.xfire.transport.AbstractChannel.receive(AbstractChannel.java:38) at org.codehaus.xfire.transport.http.XFireServletController.invoke(XFireServletController.java:304) at org.codehaus.xfire.transport.http.XFireServletController.doService(XFireServletController.java:129) at org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:116) at javax.servlet.http.HttpServlet.service(HttpServlet.java:709) at javax.servlet.http.HttpServlet.service(HttpServlet.java:802) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:480) It clearly looks like there is a header validation problem. Any suggestions? For sake of completeness, here is my modified MyXfireServlet. package ch.qos.arte; import ...; public class MyXfireServlet extends XFireServlet { private static final long serialVersionUID = 14536657L; Logger logger = LoggerFactory.getLogger(MyXfireServlet.class); public XFire createXFire() throws ServletException { logger.debug("createXFire() called"); try { XFire xfire = (XFire) getServletContext().getAttribute(XFIRE_INSTANCE); if (xfire == null) { XFireFactory factory = XFireFactory.newInstance(); xfire = factory.getXFire(); ((DefaultXFire) xfire).addInHandler(new AddressingInHandler()); ((DefaultXFire) xfire).addOutHandler(new AddressingOutHandler()); Service echoService = registerServiceAnnotation(xfire, new EchoServiceImpl(), new QName("http://www.qos.ch/arte", "EchoService")); xfire.getServiceRegistry().register(echoService); getServletContext().setAttribute(XFIRE_INSTANCE, xfire); } return xfire; } catch (Exception e) { logger.error("Couldn't start XFire", e); throw new ServletException("Couldn't start XFire.", e); } } Service registerServiceAnnotation(XFire xfire, Object serviceImpl, QName qname) { AnnotationServiceFactory factory = new MyServiceFactory(xfire.getTransportManager()); Service service = factory.create(serviceImpl.getClass()); service.setName(qname); return service; } } package ch.qos.arte; import org.codehaus.xfire.addressing.AddressingOperationInfo; import org.codehaus.xfire.jaxws.JAXWSServiceFactory; import org.codehaus.xfire.service.OperationInfo; import org.codehaus.xfire.service.Service; import org.codehaus.xfire.transport.TransportManager; import java.lang.reflect.Method; /** * @author xpbo * * This class registers an AddressingOperationInfo object with an * OperationInfo, as required to support WS-Addressing. */ public class MyServiceFactory extends JAXWSServiceFactory { public MyServiceFactory(TransportManager transportManager) { super(transportManager); } /** * Forces a new AddressingOperationInfo object to be registered with the * OperationInfo. */ @Override protected OperationInfo addOperation(Service endpoint, Method method, String style) { OperationInfo op = super.addOperation(endpoint, method, style); /* * The AddressingOperationInfo ctor registers itself so nothing need be done * with the new object in this method. * * The "Response" string is appended to the action to provide a return * string that matches that expected by the C# client. */ String action = getAction(op); new AddressingOperationInfo(action, action + "Response", null, op); return op; } } "Phil Bowker" <[EMAIL PROTECTED]> 16.03.2007 12:23 Please respond to [email protected] To [email protected] cc Subject Re: [xfire-user] web-service using Xfire+JSR181+WS-Addressing Reviewed by Category Ceki, To use Ws-Addressing you need to force the load of an AddressingOperationInfo object. The following code will do this for you: /** * @author xpbo * * This class registers an AddressingOperationInfo object with an * OperationInfo, as required to support WS-Addressing. */ public class MyServiceFactory extends JAXWSServiceFactory { /** * Forces a new AddressingOperationInfo object to be registered with the * OperationInfo. */ @Override protected OperationInfo addOperation( Service endpoint, Method method, String style) { OperationInfo op = super.addOperation(endpoint, method, style); /* * The AddressingOperationInfo ctor registers itself so nothing need * be done with the new object in this method. * * The "Response" string is appended to the action to provide a * return string that matches that expected by the C# client. */ String action = getAction(op); new AddressingOperationInfo(action, action + "Response", null, op); return op; } } Be sure then to register this class in your config. Phil ************************ DISCLAIMER ************************ This message is intended only for use by the person to whom it is addressed. It may contain information that is privileged and confidential. Its content does not constitute a formal commitment by Lombard Odier Darier Hentsch Group and any of its affiliates. If you are not the intended recipient of this message, kindly notify the sender immediately and destroy this message. Thank You. *****************************************************************
