Ok, try this ...

/**
* @author xpbo
*
* When a WS client uses the SOAP "mustUnderstand" feature XFire must be
* informed which QNames (see <code>javax.xml.namespace.QName</code>) the WS can
* handle.
* This class extends an XFire handler to provide the QNames handled
by MyProject.
* Note: Any handler could be extended to force this registration.
*/
public class MyProjectAddressingInHandler extends AddressingInHandler {
        
        // QNames for the Action and To SOAP header elements as used in 
MyProject
        private static QName[] qNames =
                { new QName("http://www.w3.org/2005/08/addressing";, "Action"),
                  new QName("http://www.w3.org/2005/08/addressing";, "To") };

        /**
         * Returns QNames for SOAP header elements that must be known by XFire 
if
         * the WS client uses the SOAP "mustUnderstand" feature.
         *
         * @return      The array of QNames.
         */
        public QName[] getUnderstoodHeaders()
   {
       return qNames;
   }
}


Good luck.

Phil


On 16/03/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:

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]




[EMAIL PROTECTED]

cc

SubjectRe: [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.
*****************************************************************


---------------------------------------------------------------------
To unsubscribe from this list please visit:

   http://xircles.codehaus.org/manage_email

Reply via email to