简体   繁体   English

如何使用JAX-WS客户端指定WS-Addressing版本?

[英]How do I specify the WS-Addressing version with a JAX-WS client?

I generated a SOAP 1.2 web service client with wsimport (JDK 1.7). 我使用wsimport(JDK 1.7)生成了SOAP 1.2 Web服务客户端。 I need it to explicitly use WS-Addressing 2004/08 and not 2005/08. 我需要它来显式使用WS-Addressing 2004/08,而不是2005/08。 The closest I could find for instanciating the client was 我能找到的最能说明客户的是

import MyService.*;
import javax.xml.ws.BindingProvider;

public class test {

    public static void main(String[] args) {
        MyService service = new MyService();  
        IMyService proxy = service.getMyService(new javax.xml.ws.soap.AddressingFeature(true, true) );  
        ((BindingProvider)proxy).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://192.168.0.5:1234/services/MyService");
        proxy.Ping("Foo");
      }
}

The important bit being 重要的是

MyService service = new MyService();
IMyService proxy = service.getMyService(new javax.xml.ws.soap.AddressingFeature(true, true));

Unfortunately, this results in 2005/08 addressing. 不幸的是,这导致了2005/08年的解决。 Not supplying an argument to getMyService() results in not using WS-Addressing. 不向getMyService()提供参数会导致不使用WS-Addressing。

The only examples I can find on Google that force 2004/08 Addressing use Axis2 (the whole reason I want JAX-WS is to move away from Axis2) 我在Google上发现的唯一迫使2004/08寻址的示例都使用Axis2(我希望JAX-WS的全部原因是远离Axis2)

The difference on the wire is (2004/08) 电线上的区别是(2004/08)

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing">
    <s:Header>
        <a:Action s:mustUnderstand="1">http://www.example.com/schemas/service/myservice/IMyService/Ping</a:Action>
        <a:MessageID>urn:uuid:87727401-b1a0-4667-9ef0-c64e58800ff6</a:MessageID>
        <a:ReplyTo>
            <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
        </a:ReplyTo>
        <a:To s:mustUnderstand="1">https://192.168.0.5:1234/services/MyService</a:To>
    </s:Header>
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <Ping xmlns="http://www.example.com/schemas/service/myservice">
            <Message>Foo</Message>
        </Ping>
    </s:Body>
</s:Envelope>

(2005/08) (2005/08)

<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope">
    <S:Header>
        <To xmlns="http://www.w3.org/2005/08/addressing">https://192.168.0.5:1234/services/MyService</To>
        <Action xmlns="http://www.w3.org/2005/08/addressing" xmlns:S="http://www.w3.org/2003/05/soap-envelope" S:mustUnderstand="true">http://www.example.com/schemas/service/myservice/IMyService/Ping</Action>
        <ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
            <Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
        </ReplyTo>
        <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:87727401-b1a0-4667-9ef0-c64e58800ff6</MessageID>
    </S:Header>
    <S:Body>
        <Ping xmlns="http://www.example.com/schemas/service/myservice">
            <Message>Foo</Message>
        </Ping>
    </S:Body>
</S:Envelope>

Anyone have any ideas here? 有人在这里有什么想法吗?

I found a way to do this, but I'm not convinced that it's the best solution. 我找到了一种方法来执行此操作,但是我不认为这是最好的解决方案。

It involves creating a custom SOAPHandler and manually injecting the Addressing headers and stripping out the HTTP header soapaction 它涉及创建自定义SOAPHandler并手动注入Addressing头并剥离HTTP头soapaction

public static class Addressing2004SoapHandler implements SOAPHandler<SOAPMessageContext>
{
    private String mEndpoint;

    public Addressing2004SoapHandler(String endpoint) {
        super();
        mEndpoint = endpoint;
    }

    public Set<QName> getHeaders()
    {
        Set<QName> retval = new HashSet<QName>();
        retval.add(new QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "Action"));
        retval.add(new QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "MessageID"));
        retval.add(new QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "ReplyTo"));
        retval.add(new QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "To"));
        return retval;
    }

    public boolean handleMessage(SOAPMessageContext messageContext)
    {
        Boolean outboundProperty = (Boolean)messageContext.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (outboundProperty.booleanValue()) {
            try {
                messageContext.put(MessageContext.HTTP_REQUEST_HEADERS, Collections.singletonMap("Content-Type",Collections.singletonList("application/soap+xml; charset=utf-8")));
                SOAPMessage message = messageContext.getMessage();
                if(message.getSOAPPart().getEnvelope().getHeader() == null) {
                        message.getSOAPPart().getEnvelope().addHeader();
                }
                SOAPHeader header = message.getSOAPPart().getEnvelope().getHeader();
                SOAPHeaderElement actionElement = header.addHeaderElement(new QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "Action"));
                actionElement.setMustUnderstand(true);
                String action = (String)messageContext.get("javax.xml.ws.soap.http.soapaction.uri");
                messageContext.put("javax.xml.ws.soap.http.soapaction.uri", null);
                actionElement.addTextNode(action);
                header.addHeaderElement(new QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "MessageID")).addTextNode("uuid:" + UUID.randomUUID().toString());
                SOAPHeaderElement replyToElement = header.addHeaderElement(new QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "ReplyTo"));
                SOAPElement addressElement = replyToElement.addChildElement(new QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "Address"));
                addressElement.addTextNode("http://www.w3.org/2004/08/addressing/anonymous");
                SOAPHeaderElement toElement = header.addHeaderElement(new QName("http://schemas.xmlsoap.org/ws/2004/08/addressing", "To"));
                toElement.setMustUnderstand(true);
                String endpoint = (String)messageContext.get("javax.xml.ws.service.endpoint.address");
                toElement.addTextNode(endpoint);
            }
            catch(SOAPException ex) {
            }
        }

        return true;
    }

    public boolean handleFault(SOAPMessageContext messageContext)
    {
            return true;
    }
    public void close(MessageContext messageContext)
    {
    }
}

Here is the updated test Class 这是更新的测试班

public class test {
    public static void main(String[] args) {
        MyService service = new MyService();  
        IMyService proxy = service.getMyService();  
        javax.xml.ws.Binding binding = ((BindingProvider)proxy).getBinding();
        List<Handler> handlerList = binding.getHandlerChain();
        handlerList.add(new Addressing2004SoapHandler(endpoint));
        binding.setHandlerChain(handlerList);
        Map<String, Object> requestContext = ((BindingProvider)proxy).getRequestContext();
        requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://192.168.0.5:1234/services/MyService");
        proxy.Ping("Foo");
    }
}

There is a side effect, I've not yet figured out how to solve, this results in a <?xml version="1.0"?> xml declaration which conflicts with the HTTP Content-type. 有一个副作用,我尚未弄清楚如何解决,这导致<?xml version =“ 1.0”?> xml声明与HTTP Content-type冲突。 I'll post an update when I've figured that out. 确定后,我会发布更新。

I used the MemberSubmissionAddressingFeature from jaxws-rt 我使用了来自jaxws-rt的MemberSubmissionAddressingFeature

IMyService proxy = service.getMyService(new com.sun.xml.ws.developer.MemberSubmissionAddressingFeature(true, true) );

this is the pom file dependency for maven http://mvnrepository.com/artifact/com.sun.xml.ws/jaxws-rt/2.2.7 这是Maven的pom文件依赖性http://mvnrepository.com/artifact/com.sun.xml.ws/jaxws-rt/2.2.7

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM