一、Handler說明
Handler用于處理Soap消息,如控制Header(如隐式的添加使用者資訊等)
Handler分成LogicalHandler和SOAPHandler,常用為SOAPHandler;用戶端先處理LogicalHeader再處理SOAPHandler,伺服器反之
二、開始前的準備
1、服務端
(1)接口:
@WebService
public interface UserService {
@WebResult(name="registerResult")
public String register(@WebParam(name="user") User user);
}
(2)實作:
@WebService(endpointInter, serviceName="UserServiceImplService")
public class UserServiceImpl implements UserService{
@Override
public String register(User user) {
System.out.println(user);
return user.getName() + ", registered!";
}
}
(3)啟動:
public class StartMain {
public static void main(String[] args) {
Endpoint.publish("http://localhost:8888/userinfo", new UserServiceImpl());
}
}
2、用戶端
(1) 通過wsimport生成相關代碼後,調用服務端編碼:
public class Client {
public static void main(String[] args) {
UserServiceImplService usis = new UserServiceImplService();
UserService service = usis.getUserServiceImplPort();
User user = new User();
user.setId(1);
user.setName("admin");
user.setPass("12345");
System.out.println(service.register(user));
}
}
(2)執行
/**
* 可以完成調用并傳回
*/
admin, registered!
三、添加Handler
1、服務端
(1)自定義Handler繼承SOAPHandler<T>
public class HeaderHandlerServer implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
try {
/**
* True表示Out消息,False表示In消息
*/
Boolean messageTag = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
/**
* 服務端驗證,In的時候
*/
if(messageTag == false){
SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
/**
* 如果header為空或者沒有元素,這裡判斷是否沒有元素用的是examineAllHeaderElements()方法
*/
if(header == null || ! header.examineAllHeaderElements().hasNext()){
SOAPFault fault = envelope.getBody().addFault();
fault.setFaultString("驗證資訊為空!");
throw new SOAPFaultException(fault);
}else{
/**
* 将header的所有元素提取為Iterator。需要注意的是,extractAllHeaderElements()隻能在Header中提取一次
*/
Iterator<SOAPHeaderElement> iterator = header.extractAllHeaderElements();
if(iterator.hasNext()){
SOAPHeaderElement headerEle = iterator.next();
/**
* 擷取用戶端傳遞過來的需要驗證的資訊
*/
System.out.println(headerEle.getTextContent());
/**
* 後續的驗證處理
*/
}
}
}
/**
* 如果Catch Exception,SOAPFaultException将不能到用戶端
*/
} catch (SOAPException e) {
e.printStackTrace();
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
@Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
@Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
}
(2)編輯handler-chains配置檔案
<?xml version="1.0" encoding="UTF-8"?>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<javaee:handler-chain>
<javaee:handler>
<javaee:handler-class>com.xilen.handler.HeaderHandlerServer</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
(3)在服務上添加Handler
/**
* 添加Header,通過在服務的實作類上注解@HandlerChain并指定其配置
*/
@WebService(endpointInter, serviceName="UserServiceImplService")
@HandlerChain(file="jax-handler.xml")
public class UserServiceImpl implements UserService{
@Override
public String register(User user) {
System.out.println(user);
return user.getName() + ", registered!";
}
}
(4)測試這個Handler的效果
/**
* 在用戶端沒有添加相關Header以攜帶使用者資訊時調用服務端,将在用戶端抛出如下異常
*/
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: 驗證資訊為空!
at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(Unknown Source)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown Source)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(Unknown Source)
at com.sun.proxy.$Proxy21.register(Unknown Source)
at com.xilen.Client.main(Client.java:19)
2、用戶端
(1)自定義Handler繼承SOAPHandler<T>
public class HeaderHandlerClient implements SOAPHandler<SOAPMessageContext> {
@Override
public boolean handleMessage(SOAPMessageContext context) {
try {
/**
* True表示Out False表示In
*/
Boolean messageTag = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
/**
*如果是Out
*/
if(messageTag){
SOAPMessage message = context.getMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
SOAPHeader header = envelope.getHeader();
if(header == null){
/**
* 通過envelope方式擷取hander,主要是為了能夠在Header為空的時候,通過envelope.addHeader()方法添加Header
*/
header = envelope.addHeader();
}
/**
* 添加Header資訊
*/
QName headerQName = new QName("http://impl.jws.xilen.com/", "info", "ns");
header.addHeaderElement(headerQName).setValue("admin");
/**
* 列印整個SOAP消息
*/
message.writeTo(System.out);
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
public boolean handleFault(SOAPMessageContext context) {
System.out.println("fault");
return false;
}
@Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
@Override
public Set<QName> getHeaders() {
// TODO Auto-generated method stub
return null;
}
}
(2)編輯handler-chains配置檔案
<?xml version="1.0" encoding="UTF-8"?>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<javaee:handler-chain>
<javaee:handler>
<javaee:handler-class>com.xilen.HeaderHandlerClient</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
(3)在服務上添加Handler
<pre name="code" class="java">/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.4-b01
* Generated source version: 2.2
*
* 在通過wsimport指令生成的服務實作類(繼承了Service)的類上添加@HandlerChain以配置用戶端Handler
*/
@WebServiceClient(name = "UserServiceImplService", targetNamespace = "http://impl.jws.xilen.com/",
wsdlLocation = "http://localhost:8888/userinfo?wsdl")
@HandlerChain(file="jax-handler.xml")
public class UserServiceImplService extends Service
{
……
}
(4)再次測試Handler
/**
* 此時已經可以正确通路服務并傳回結果
*/
admin, registered!
四、一些補充
如果需要針對某一些服務即操作才做驗證,可以在Handler中通過SoapBody擷取part以判斷目前服務
@Override
public boolean handleMessage(SOAPMessageContext context) {
try {
Boolean messageTag = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if(messageTag == false){
SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
/**
* 如果需要針對某一些操作才做驗證,可以通過SoapBody擷取part做判斷
*/
String partName = envelope.getBody().getChildNodes().item(0).getLocalName();
if("list".equals(partName)){
/**
* 驗證header的邏輯
*/
SOAPHeader header = envelope.getHeader();
if(header == null || ! header.examineAllHeaderElements().hasNext()){
SOAPFault fault = envelope.getBody().addFault();
fault.setFaultString("驗證資訊為空!");
throw new SOAPFaultException(fault);
}else{
Iterator<SOAPHeaderElement> iterator = header.extractAllHeaderElements();
if(iterator.hasNext()){
SOAPHeaderElement headerEle = iterator.next();
System.out.println(headerEle.getTextContent());
}
}
}
}
} catch (SOAPException e) {
e.printStackTrace();
}
return true;
}
五、資源下載下傳
http://download.csdn.net/detail/u013379717/7463923