Java – optional part of jax-ws response message

TL; Dr: how can I have an optional < part > in response to < message > for WSDL service

I am:

>Locate an existing service > write a client to talk to the service > implement the service definition as a java interface

Problem: depending on the version of the service, there may be an additional element in the response body element

Using the following service definition, I can locate the V1 of the service:

<message name="CreateResponse">
    <part name="ResourceCreated" element="ns7:ResourceCreated" />
  </message>

This is used with V2 of the service:

<message name="CreateResponse">
    <part name="ResourceCreated" element="ns7:ResourceCreated" />
    <part name="Shell" element="ns8:Shell" />
  </message>

Question: how to use the same service definition to locate two versions? I really don't need the second element, so just ignore it

Details:

>The service is windows remote management service. > I'm writing a java client to locate it. > This code is in https://github.com/cloudsoft/winrm4j Provide > when talking with Windows 7, the create response contains a responsecreated element. > When talking to windows 2012, the create response contains two elements – responsecreated and shell

Solution

I don't believe there is a clean solution to this problem - it's impossible to mark the elements in < part > < message > as optional

The solution in this case is to remove the additional element before it reaches the Jax - WS parser This can be done by creating CXF interceptors or Jax - WS handlers and manipulating the response XML

To create a jax-ws handler:

public class StripHandler implements SOAPHandler<SOAPMessageContext> {

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        boolean isResponse = Boolean.FALSE.equals(context.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY));
        if (isResponse) {
            QName action = (QName) context.get(SOAPMessageContext.WSDL_OPERATION);
            if ("Create".equals(action.getLocalPart())) {
                Iterator<?> childIter = getBodyChildren(context);
                while(childIter.hasNext()) {
                    SOAPElement el = (SOAPElement) childIter.next();
                    if ("Shell".equals(el.getLocalName())) {
                        childIter.remove();
                    }
                }
            }
        }
        return true;
    }

    private Iterator<?> getBodyChildren(SOAPMessageContext context) {
        try {
            SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
            SOAPBody body = envelope.getBody();
            return body.getChildElements();
        } catch (SOAPException e) {
            throw new IllegalStateException(e);
        }
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {return true;}
    @Override
    public void close(MessageContext context) {}
    @Override
    public Set<QName> getHeaders() {return null;}

}

Register jax-ws handler:

To declare

Create handlers next to the service interface XML file:

<handler-chains xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee">
    <handler-chain>
        <handler>
            <handler-name>StripHandlerr</handler-name>
            <handler-class>fully.qualified.StripHandler</handler-class>
        </handler>
    </handler-chain>
</handler-chains>

And attach it to the service definition with the annotation @ handlerchain (file = "handlers. XML")

programming

This is an alternative approach that does not require additional XML files

((BindingProvider)service).getBinding().setHandlerChain(Arrays.<Handler>asList(new StripHandler());
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>