加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – JAX-WS响应消息中的可选部分

发布时间:2020-12-15 02:17:56 所属栏目:Java 来源:网络整理
导读:TL; DR:我怎样才能有一个可选的 part在响应 message为wsdl服务. 我是: 定位现有服务 写一个客户端与服务交谈 将service definition实现为Java接口 问题: 根据服务的版本,响应Body元素中可能还有一个附加元素. 使用以下服务定义,我可以定位服务的v1: mess
TL; DR:我怎样才能有一个可选的< part>在响应< message>为wsdl服务.

我是:

>定位现有服务
>写一个客户端与服务交谈
>将service definition实现为Java接口

问题:
根据服务的版本,响应Body元素中可能还有一个附加元素.

使用以下服务定义,我可以定位服务的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>

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

细节:

>服务是Windows Remote Management Service.
>我正在编写一个Java客户端来定位它.
>该代码于https://github.com/cloudsoft/winrm4j提供
>与Windows 7交谈时,Create响应包含一个ResponseCreated元素.
>与Windows 2012交谈时,Create响应包含两个元素 – ResponseCreated和Shell.

解决方法

我不相信这个问题有一个干净的解决方案 – 不可能标记< part> < message>中的元素作为可选.

这种情况下的解决方法是在附加元素到达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());

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读