webservice调用服务端数据时给soapenv:Envelope 添加自定义的命名空间

时间:2021-04-09 20:28:53

最近做第三方接口,服务端需要

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://***.com/webservices" xmlns:cus="http://***/CustomUI">
   <soapenv:Header>
      <web:SessionType>***</web:SessionType>
      <web:PasswordText>***</web:PasswordText>
      <web:UsernameToken>***</web:UsernameToken>
   </soapenv:Header>
   <soapenv:Body>
      <cus:HQHPExpenseVoucherFlowServiceApprove_Input>
          ......................
      </cus:HQHPExpenseVoucherFlowServiceApprove_Input>
   </soapenv:Body>
</soapenv:Envelope>

服务端添加了 header验证,项目用的是cxf,按照之前的思路,就是在客户端调用时直接添加拦截器,

在拦截器中添加hear 验证需要的内容,

拦截器中传递的内容是

<soapenv:Header>
          <SessionType>***</web:SessionType>
          <PasswordText>***</web:PasswordText>
          <UsernameToken>***</web:UsernameToken>
   </soapenv:Header>

调用客户端时就直接验证失败,错误错误就是soapenv:Envelope中添加需要添加一个xmlns:web="http://***.com/webservices" 的命名空间

问题找到了,然后就就是漫长的查质料,怎么样在soapenv:Envelope中添加命名空间,网上居然搜不到解决方案.

最后发现可能思路有点局限了,一直都停留在cxf 的结局方案,经过漫长的测试下终于得到结局,贴下解决方案希望可以帮到更多的程序员朋友

1,配置jaxws:handlers

(1)在webservice配置文件中添加jaxws:handlers(这个具体是什么东西百度一下这里不解释)

<jaxws:client id="client"  serviceClass="com.webService.client.crm.reimburse.xxxxxxSpcService"
     address="xxxxxx">
               
               <!-- 用户名密码验证 -->
               <jaxws:handlers>
                    <bean class="com.webService.client.handler.xxxxHandler"></bean>
               </jaxws:handlers>
           
     </jaxws:client>

(2)xxxxHandler中的代码

package com.webService.client.handler;

import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class SiebelHeaderHandler implements SOAPHandler<SOAPMessageContext> {
   
         public  SiebelHeaderHandler(){
             System.out.println("crm,handler 用户验证加载成功........................");
         }

public boolean handleMessage(SOAPMessageContext context) {
            Boolean isRequest = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
            QName usernameQName = new QName("http://xxx.com/webservices", "UsernameToken","siebelwsh");
            QName passwordQName = new QName("http://xxx.com/webservices", "PasswordText","siebelwsh");
            QName sessionTypeQName = new QName("http://xxx.com/webservices", "SessionType","siebelwsh");

if (isRequest) {
                try {
                    SOAPMessage soapMsg = context.getMessage();
                    SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();
                    SOAPHeader soapHeader = soapEnv.getHeader();
                    soapEnv.addNamespaceDeclaration("web", "http://xxxxx.com/webservices");
                    //if no header, add one
                    if (soapHeader == null) {
                        soapHeader = soapEnv.addHeader();
                    }
                 
                       String username = "xxx";
                       String password = "xxxx";
           
                       //添加SiebelUsernameToken
                       SOAPHeaderElement usernameHeaderElement = soapHeader.addHeaderElement(usernameQName);
                       usernameHeaderElement.addTextNode(username);
                       //添加SiebelPasswordText
                       SOAPHeaderElement passwordHeaderElement = soapHeader.addHeaderElement(passwordQName);
                       passwordHeaderElement.addTextNode(password);
                       //添加SiebelSessionType
                       SOAPHeaderElement SessionTypeHeaderElement = soapHeader.addHeaderElement(sessionTypeQName);
                       SessionTypeHeaderElement.addTextNode("None");
                        soapMsg.saveChanges();
                } catch (SOAPException e) {
                    //logger.warn(e.getMessage());
                } catch (Exception e) {
                    //logger.error(e.getMessage(),e);
                }

}
           
            return true;
        }

public Set<QName> getHeaders() {
            return null;
        }

@Override
        public boolean handleFault(SOAPMessageContext context) {
            // TODO Auto-generated method stub
            return false;
        }

@Override
        public void close(MessageContext context) {
            // TODO Auto-generated method stub
            
        }
    }

添加Handler后顺利通过;

注意:其实这里<web:SessionType>***</web:SessionType> 的web可以相当于是一个变量 xmlns:web="http://***.com/webservices"