【问题标题】:removing mustUnderstand attribute from soap headers从肥皂标题中删除 mustUnderstand 属性
【发布时间】:2011-11-20 08:24:07
【问题描述】:

如何从轴客户端的soap头中删除mustunderstand属性。即使我没有特别设置它,当我设置soap头信息mustundertand并且actor属性会自动添加到soap消息中。有人知道如何删除它们吗? 我正在使用 Axis2 1.4 版本的 wsdl2java 来创建我的 ws 客户端。

【问题讨论】:

    标签: java soap axis


    【解决方案1】:

    这些解决方案都不适合我,因为:

    查看“Adding ws-security to wsdl2java generated classes”的答案帮助我编写了一个适合我的解决方案:

    void addSecurityHeader(Stub stub, final String username, final String password) {
      QName headerName = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security");  // Or any other namespace that fits in your case
      AtomicReference<SOAPHeaderElement> header 
        = new AtomicReference<SOAPHeaderElement>
            (new SOAPHeaderElement(headerName) {                       
               {  
                 SOAPElement utElem = addChildElement("UsernameToken");
                 utElem.addChildElement("Username").setValue(username);
                 utElem.addChildElement("Password").setValue(password);
               }
               @Override
               public void setAttribute(String namespace, String localName, String value) {
                 if (!Constants.ATTR_MUST_UNDERSTAND.equals(localName)) {  // Or any other attribute name you'd want to avoid
                   super.setAttribute(namespace, localName, value);
                 }
               }
            });
      SOAPHeaderElement soapHeaderElement = header.get();
      soapHeaderElement.setActor(null);      // No intermediate actors are involved.
      stub.setHeader(soapHeaderElement);  // Finally, attach the header to the stub
    }
    

    【讨论】:

    • 救了我一命... thnx
    • 这非常有效!谢谢。我不想要任何子节点,因此我使用了这个: new SOAPHeaderElement(headerName) { { setValue(value); }
    • 谢谢!这个应该被接受为这个问题的有效答案。 SOAPHeaderElement 类默认将 mustUnderstand 和 actor 属性添加到标头,这是(到目前为止)通过过滤首先添加/设置来删除它的唯一方法。
    【解决方案2】:

    如果您想在您拥有的 AXIS 客户端中禁用必须了解的检查 将以下行添加到您的代码中:

    _call.setProperty(Call.CHECK_MUST_UNDERSTAND, new Boolean(false));
    

    那么永远不会调用 AXIS 客户端的 MustUnderstandChecker

    【讨论】:

      【解决方案3】:

      在我的情况下,它可以手动从 SOAPHeader

      中删除该属性
      SOAPHeader header = env.getHeader();
      OMChildrenQNameIterator childrenWithName = (OMChildrenQNameIterator) header.getChildrenWithName(omElementauthentication.getQName());
          while (childrenWithName.hasNext()) {
              org.apache.axiom.om.OMElement omElement = (org.apache.axiom.om.OMElement) childrenWithName.next();
              QName mustAnderstandQName = omElement.resolveQName("soapenv:mustUnderstand");
              if (mustAnderstandQName == null) {
                  continue;
              }
              OMAttribute mustAnderstandAttribute = omElement.getAttribute(mustAnderstandQName);
                  if (mustAnderstandAttribute == null) {
                      continue;
                  }
              omElement.removeAttribute(mustAnderstandAttribute);
          }
      

      【讨论】:

        【解决方案4】:

        我最近遇到了类似的情况,通过谷歌搜索,我设法找到了以下解决方案。

        使用过 Axis2,您可能已经生成了一个 MyWSStub 文件,其中包含对您的服务的调用。 创建一个扩展您的存根的包装类(最好不要触摸自动生成的存根文件),例如MyWSStubWrapper:

        public class MyWSStubWrapper extends MyWSStub {
        
        /**
         * @throws AxisFault
         */
        public MyWSStubWrapper() throws AxisFault {
        }
        
        /**
         * @param configurationContext
         * @throws AxisFault
         */
        public MyWSStubWrapper(ConfigurationContext configurationContext) throws AxisFault {
            super(configurationContext);
        }
        
        /**
         * @param targetEndpoint
         * @throws AxisFault
         */
        public MyWSStubWrapper(String targetEndpoint) throws AxisFault {
            super(targetEndpoint);
        }
        
        /**
         * @param configurationContext
         * @param targetEndpoint
         * @throws AxisFault
         */
        public MyWSStubWrapper(ConfigurationContext configurationContext, String targetEndpoint) throws AxisFault {
            super(configurationContext, targetEndpoint);
        }
        
        /**
         * @param configurationContext
         * @param targetEndpoint
         * @param useSeparateListener
         * @throws AxisFault
         */
        public MyWSStubWrapper(ConfigurationContext configurationContext, String targetEndpoint, boolean useSeparateListener) throws AxisFault {
            super(configurationContext, targetEndpoint, useSeparateListener);
        }
        
        @Override
        protected void addHeader(OMElement omElementToadd, SOAPEnvelope envelop, boolean mustUnderstand) {
            SOAPHeaderBlock soapHeaderBlock = envelop.getHeader().addHeaderBlock(omElementToadd.getLocalName(), omElementToadd.getNamespace());
            OMNode omNode = null;
        
            // add child elements
            for (Iterator iter = omElementToadd.getChildren(); iter.hasNext();) {
                omNode = (OMNode) iter.next();
                iter.remove();
                soapHeaderBlock.addChild(omNode);
            }
        
            OMAttribute omatribute = null;
            // add attributes
            for (Iterator iter = omElementToadd.getAllAttributes(); iter.hasNext();) {
                omatribute = (OMAttribute) iter.next();
                soapHeaderBlock.addAttribute(omatribute);
            }
        }
        

        }

        请记住,上面的代码将从您的标题中完全删除soapenv:mustUnderstand="0|1" 如果您想添加您需要调用soapHeaderBlock.setMustUnderstand(true|false);代码中的某处。

        【讨论】:

          【解决方案5】:

          1) 您是否使用了 Axis SOAPHeaderElement,如果是,您是否将 mustUnderstand 设置器设置为 false?

          2) 由于您使用 wsdl2java 生成客户端,因此 WSDL(或更准确地说,模式)很可能在 SOAP 绑定中引用的元素上包含 mustUnderstand 属性。所以当wsdlToJava生成客户端代码的时候,那些属性自然会加进去。有关 mustUnderstand 属性的说明,请参见 here。 如果修改 WSDL 是不可能的,并且您必须从标头中删除此属性,那么我想您可以尝试使用处理程序来做到这一点

          3) 不可取,但如果您真的必须删除此属性,那么我想您可以添加一个更改标头的客户端处理程序:http://ws.apache.org/axis/java/apiDocs/org/apache/axis/handlers/package-summary.html

          【讨论】:

          • 1) 是的,我正在使用 SOAPHeaderElement,但我尝试了两者都没有设置 mustunderstand 并将其设置为 false。实际上没有任何改变。我的代码是这样的: SOAPHeaderElement header = new SOAPHeaderElement("ns1://x.x.x.x/abc.asmx", "AuthHeader"); SOAPElement 节点 = header.addChildElement("user_1"); node.addTextNode("abc"); SOAPElement node2 = header.addChildElement("pass_1"); node2.addTextNode("123"); _call.addHeader(header);
          • 当您说没有任何变化时,您的意思是 SOAP 标头总是以 mustUnderstand=false 出现吗?您是否有可以发布的 WSSDL/模式(如果内容很长,请不要发布整个内容……只发布相关部分)。
          • 是的,我的意思正是如此。我认为轴代码在设置soap 标头参数时在默认行为中添加了mustunderstand 和actor 属性。当我删除soap 标头的代码时,mustunderstand 和actor 参数也被删除了。跨度>
          • 相关的wsdl部分可能是x.x.x.x/Bank.asmx/xMethod" style="document" /> 输出> 操作>
          【解决方案6】:

          我正在使用带有 ws 安全性的轴 1.4 客户端

          就我而言,正如莱因哈德所说 这行得通

          MyService service = new MyServiceLocator(); 
          MyServicePortType port = service.getMyServiceHttpsSoap11Endpoint();
          
          ((Stub) port)._setProperty(Call.CHECK_MUST_UNDERSTAND, Boolean.FALSE);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-09-10
            • 2017-01-01
            相关资源
            最近更新 更多