webservice调用服务端数据时给soapenv:Envelope 添加自定义的命名空间
最近做第三方接口,服务端需要
<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"