使用Java添加Soap Action头

4
如何在Java中添加SOAP Action头?我使用以下代码在Header中测试了SoapUI中的服务:<a:Action s:mustUnderstand="1">MyServiceName</a:Action>,并根据此帖子正常工作。没有此标题,我会收到“The SOAP action specified on the message, '', does not match the HTTP SOAP Action,”错误,这是我从Java客户端应用程序中获得的相同错误。
PS:我使用Apache CXF从wsdl生成桩,并使用wsimport生成Java客户端桩尝试过JAX-WS RI。两种情况都出现了同样的错误。
您有什么想法吗?我在SO上找不到一个正确的确切帖子来解决这个问题。
这是我所尝试的内容,但我猜使用com.sun……包中的类并不推荐,可能会在不同的jdk之间引起可移植性问题。JAX-WS - Adding SOAP Headers
1个回答

4
我曾遇到类似问题,以下是解决方法。我使用wsimport生成了sei。
如果头部信息在wsdl中有定义,你可以使用-XadditionalHeaders参数生成可接受头部信息的SEI。
如果没有, 你需要通过SOAPHandler以编程方式添加头部信息。虽然很简单!
此链接提供了详细说明: http://www.javadb.com/using-a-message-handler-to-alter-the-soap-header-in-a-web-service-client/ 将方法handleMessage更改如下:
public boolean handleMessage(SOAPMessageContext smc) {

    Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

    if (outboundProperty.booleanValue()) {

        SOAPMessage message = smc.getMessage();

        try {
            SOAPFactory soapFactory = SOAPFactory.newInstance();
            SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
            SOAPHeader header = envelope.addHeader();
            SOAPHeaderElement se=header.addHeaderElement(new QName("http://schemas.microsoft.com/ws/2005/05/addressing/none", "Action"));
            //se.setMustUnderstand(true); //Ideal way to set if webservice supports
            se.addTextNode("some text");
            se.addAttribute(soapFactory.createName("S:mustUnderstand"),"1"); //S: or s: depending on xmlns

        } catch (Exception e) {
            e.printStackTrace();
        }

    } else {
        try {
            SOAPMessage message = smc.getMessage();
            message.writeTo(System.out);
            System.out.println("");

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    return true;
}

//代码来附加处理程序。

Service1 service1 = new Service1();
        IService1 iService1 = service1.getBasicHttpBindingIService1();

        BindingProvider bindingProvider = (BindingProvider) iService1;
        final Binding binding = bindingProvider.getBinding();
        List<Handler> handlerList = binding.getHandlerChain();

        if (handlerList == null) {
            handlerList = new ArrayList<Handler>();
        }

        handlerList.add(new HeaderHandler());
        binding.setHandlerChain(handlerList);
        ServiceResponse serviceResponse = iService1.callServiceMethod1(serviceRequest);

谢谢,但链接中并没有显示您实际调用handleMessage方法的位置?另外,我们从哪里获取SOAPMessageContext参数以将其传递给handleMessage呢? - james2611nov
谢谢。这几乎为我完成了工作。但是我使用了@HandlerChain(file="handler-chain.xml")将上述处理程序链接到生成的代理服务。更多细节请参见:http://www.mkyong.com/webservices/jax-ws/jax-ws-soap-handler-in-client-side/ - james2611nov
抱歉回复晚了。这是我编写的调用方法的代码。 - Bharath V N
如果头文件是wsdl的一部分,您可以使用-XadditionalHeaders生成接受头文件的SEI。我想尝试将头文件添加到WSDL文件中,但不知道如何操作。wsimport.exe将soap操作放在“Content-Type”http头中,然后服务说SOAP消息中缺少Action头。WSDL将Action指定为<binding ..>部分内<operation ..>元素的属性。如果我可以在头部分中指定Action作为“header”元素,也许wsimport.exe会生成可工作的代码。 - sb4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接