使用 Java 添加 Soap 操作标头

Posted

技术标签:

【中文标题】使用 Java 添加 Soap 操作标头【英文标题】:Adding Soap Action Header using Java 【发布时间】:2015-06-21 14:52:50 【问题描述】:

如何在 java 中添加肥皂动作标头。我在 Header 中使用 <a:Action s:mustUnderstand="1">MyServiceName</a:Action> 在 SoapUI 中测试了该服务,并且根据这篇文章 SOAP Action mismatch error while testing a WCF service with SoapUI 它可以正常工作。如果没有此标头,我会收到 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 上用 Java 解决这个问题的正确结论性帖子。

这是我尝试过的,但我猜不推荐使用 com.sun... 包中的类,这可能会导致跨不同 jdks 的可移植性问题。JAX-WS - Adding SOAP Headers

【问题讨论】:

【参考方案1】:

我遇到了类似的问题,这对我有用。我使用 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? 谢谢。这几乎完成了我的工作。但是我使用 @HandlerChain(file="handler-chain.xml") 将上面的 Handler 链接到代理生成的服务。更多细节在这里:mkyong.com/webservices/jax-ws/… 抱歉延迟回复。这是我为调用该方法而编写的代码。 "如果标头是 wsdl 的一部分,您可以使用 -XadditionalHeaders 生成接受标头的 SEI。" .....我想尝试一下,将标头添加到 WSDL 文件中,但不知道该怎么做。 wsimport.exe 将soap 操作放在“Content-Type”http 标头中,该服务表示 SOAP 消息中缺少 Action 标头。 WSDL 将 Action 指定为 部分内的 元素的属性。如果我可以将 Action 指定为 header 部分中的“header”元素,也许 wsimport.exe 会生成工作代码。

以上是关于使用 Java 添加 Soap 操作标头的主要内容,如果未能解决你的问题,请参考以下文章

在 Wcf 自定义发送端口上生成 SOAP 操作标头

HTTP 标头或 SOAP 标头中的 WCF 肥皂操作?

删除 Soap 标头和命名空间

如何使用 Savon 向 SOAP 标头添加属性?

如何向 VB.NET 2008 SOAP 请求添加标头?

如何将 HTTP 标头添加到 SOAP 客户端