如何根据以下 Web 服务客户端迭代所有 Child 元素 SOAP Headers

How to Iterate all Child Element SOAP Headers as per the below web service client

基本上我正在尝试根据下面的文章 link 编写 JAX-WS 服务端代码。

web服务客户端handleMessage中的代码(完整代码在http://informatictips.blogspot.com/2013/09/using-message-handler-to-alter-soap.html中)

SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
username.addTextNode("TestUser");
SOAPElement password = usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode("TestPassword"); ```

Now how to write relevant server side code for below input soap xml

 <s:header>
  <wsse:security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">                              
       <wsse:usernametoken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">                              
            <wsse:username>TestUser</wsse:username>
            <wsse:password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPassword</wsse:password>
       </wsse:usernametoken>
  </wsse:security>
</s:header>

我能够编写用于验证 OASIS 的 WebService -Security Headers 的服务器端处理程序代码,PFB handlerMessage(.) 方法看起来像。

输入XML

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  <SOAP-ENV:Header>
     <wsse:security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">                              
          <wsse:usernametoken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">                              
               <wsse:username >TestUser</wsse:username>
               <wsse:password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPassword</wsse:password>
          </wsse:usernametoken>
     </wsse:security>
</SOAP-ENV:Header>
   <S:Body>
      <ns2:getAreaDeatilsByPinCode xmlns:ns2="http://contract.webservice.room/">
         <arg0>12</arg0>
      </ns2:getAreaDeatilsByPinCode>
   </S:Body>
</S:Envelope>

@Override
    public boolean handleMessage(SOAPMessageContext soapMessageContext) {

        // WS-Security - Publisher - OASIS,  Namespace URI 
        final String WSSE_NS_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
        // Qualifier with header elements 
        final QName QNAME_WSSE_USERNAMETOKEN = new QName(WSSE_NS_URI, "usernametoken");
        final QName QNAME_WSSE_USERNAME = new QName(WSSE_NS_URI, "username");
        final QName QNAME_WSSE_PASSWORD = new QName(WSSE_NS_URI, "password");

        String wsseUsername = null;
        String wssePassword = null;

        System.out.println("Handler trigger for " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        Boolean isRequest = (Boolean) soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (!isRequest) {
            try {

                SOAPHeader header = soapMessageContext.getMessage().getSOAPHeader();
                if (header == null) {
                    header = soapMessageContext.getMessage().getSOAPPart().getEnvelope().addHeader();
                    generateSOAPErrMessage(soapMessageContext.getMessage(), "No SOA Header");
                }
                // Get client data from SOAP headers
                Iterator<?> headerElements = header.examineAllHeaderElements();
                while (headerElements.hasNext()) {
                    SOAPHeaderElement headerElement = (SOAPHeaderElement) headerElements.next();
                    if (headerElement.getElementName().getLocalName().equals("security")) {
                        System.out.println("inside security");
                        SOAPHeaderElement securityElement = headerElement;
                        Iterator<?> securityChildern = securityElement.getChildElements();
                        while (securityChildern.hasNext()) {
                            System.out.println("inside securityChildern");
                            Node node = (Node) securityChildern.next();
                            if (node instanceof SOAPElement) {
                                System.out.println("insdie node...");
                                SOAPElement element = (SOAPElement) node;
                                QName elementQname = element.getElementQName();
                                if (QNAME_WSSE_USERNAMETOKEN.equals(elementQname)) {

                                    System.out.println("validating username and password...");
                                    SOAPElement usernameTokenElement = element;
                                    wsseUsername = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_USERNAME);
                                    wssePassword = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_PASSWORD);
                                    if(!wsseUsername.equals("TestUser") || !wssePassword.equals("TestPassword")){
                                        generateSOAPErrMessage(soapMessageContext.getMessage(), "username and password are wrong....");
                                    }
                                    System.out.println("username::"+wsseUsername+ " , password::"+wssePassword);
                                    break;
                                }
                            }
                        }
                        if (wsseUsername != null) {
                            break;
                        }
                    }
                }

            } catch (SOAPException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    private String getFirstChildElementValue(SOAPElement usernameTokenElement, QName qNAME_WSSE_USERNAME) {

        System.out.println("get username and password");
        String value = null;
        Iterator<?> usernameTokenChilderen = usernameTokenElement.getChildElements(qNAME_WSSE_USERNAME);

        while (usernameTokenChilderen.hasNext()) {
            System.out.println("get the child elment for username and password");
            SOAPElement childElement = (SOAPElement) usernameTokenChilderen.next();
            value = childElement.getValue();
        }

        return value;
    }

    private void generateSOAPErrMessage(SOAPMessage message, String cause) {

        try {
            SOAPBody faultBody = message.getSOAPPart().getEnvelope().getBody();

            SOAPFault soapFault = faultBody.addFault();
            soapFault.setFaultString(cause);
            throw new SOAPFaultException(soapFault);

        } catch (SOAPException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

有效请求


    <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
       <S:Body>
          <ns2:getAreaDeatilsByPinCodeResponse xmlns:ns2="http://contract.webservice.room/">
             <return>
                <areaName>XXXXX</areaName>
                <location>XXXXX</location>
                <pincode>12</pincode>
                <state>XX</state>
             </return>
          </ns2:getAreaDeatilsByPinCodeResponse>
       </S:Body>
    </S:Envelope>

未经授权的请求

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
   <S:Body>
      <S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
         <faultcode>S:Server</faultcode>
         <faultstring>username and password are wrong....</faultstring>
      </S:Fault>
   </S:Body>
</S:Envelope>