【问题标题】:Optional part in JAX-WS response messageJAX-WS 响应消息中的可选部分
【发布时间】:2016-12-31 10:56:19
【问题描述】:

TL;DR:如何在 wsdl 服务的响应 中包含可选的

我是:

  • 以现有服务为目标
  • 编写客户端与服务对话
  • service definition 实现为Java 接口

问题: 根据服务的版本,响应正文元素中可能会有一个附加元素。

通过以下服务定义,我可以定位服务的 v1:

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

而且这个适用于 v2 的服务:

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

问题: 如何使用相同的服务定义来定位两个版本?我真的不需要第二个元素,所以忽略它就可以了。

详情:

【问题讨论】:

    标签: java cxf jax-ws winrm


    【解决方案1】:

    我不认为有一个干净的解决方案 - 不可能将 中的 元素标记为可选。

    在这种情况下,解决方法是在附加元素到达 JAX-WS 解析器之前将其剥离。这可以通过创建 CXF 拦截器或 JAX-WS 处理程序并操作响应 XML 来完成。

    创建 JAX-WS 处理程序:

    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;}
    
    }
    

    注册 JAX-WS 处理程序:

    声明式

    在服务接口旁边创建handlers.xml文件:

    <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>
    

    并使用注解@HandlerChain(file = "handlers.xml")将其附加到服务定义中

    以编程方式

    这是一种不需要额外 xml 文件的替代方法。

    ((BindingProvider)service).getBinding().setHandlerChain(Arrays.<Handler>asList(new StripHandler());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-18
      • 2011-10-17
      • 2013-03-05
      • 2016-11-07
      • 2012-01-09
      • 2013-12-15
      • 2018-01-30
      • 1970-01-01
      相关资源
      最近更新 更多