最近做第三方接口,服務端需要
<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"