I think I was able to find a fix on my own.
Given that o.c.xfire.addressing.AddressingInHandler understands Action
elements in the header, I decided to trick the ValidateHeadersHandler
by adding my own handler which pretends that it is able to handle
Action elements. Here it is:
public class MyInHandler extends AbstractHandler {
public void invoke(MessageContext context) throws Exception {
}
@Override
public QName[] getUnderstoodHeaders() {
QName[] qnameArray = new QName[1];
qnameArray[0] = new
QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "Action");
return qnameArray;
}
}
Adding MyInHandler as well as AddressingInHandler to my xfire instance
seems to work well. However, the fact that I need to add a
make-believe handler indicates that there might be a bug in
AddressingInHandler.
Comments?
[EMAIL PROTECTED] wrote on 16.03.2007 16:23:40:
>
> 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;
> }
> }
>
>
************************ 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.
*****************************************************************