JAX-WS - Handler詳解
一、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(endpointInterface="com.xilen.jws.UserService", 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(endpointInterface="com.xilen.jws.UserService", 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
相關文章
- JAX-WS - Soap詳解
- Android Handler原理詳解Android
- Android Handler機制詳解Android
- Message,MessageQueue,Looper,Handler詳解OOP
- [Handler]android-Handler解釋Android
- Android進階;Handler訊息機制詳解Android
- Android--Handler機制及原始碼詳解Android原始碼
- Android Handler訊息傳遞機制詳解Android
- Android之Handler訊息傳遞機制詳解Android
- Android中Handler Runnable與Thread的區別詳解Androidthread
- Android 中Message,MessageQueue,Looper,Handler詳解+例項AndroidOOP
- Handler原始碼解讀原始碼
- Handler 機制再瞭解
- Android Handler 訊息機制詳述Android
- Android Handler Looper Message 詳細分析AndroidOOP
- 詳解 Handler 訊息處理機制(附自整理超全 Q&A)
- Spring整合JAX-WSSpring
- JAX-WS - 基礎示例
- Android Handler詳細使用方法例項Android
- Handler訊息機制及handler原理(Handler,Looper,MessageQueue),自定義HandlerOOP
- 【49】瞭解new_handler的行為
- Handler全家桶之 —— Handler 原始碼解析原始碼
- Handler解析
- Handler記憶體洩漏分析及解決記憶體
- MySQL:Innodb Handler_read_*引數解釋MySql
- MySQL handler相關狀態引數解釋MySql
- Handler訊息機制完全解析Handler解析
- Android Handler機制之Handler 、MessageQueue 、LooperAndroidOOP
- jquery , find the event handler,找到jquery中的event handlerjQuery
- Handler記憶體洩漏原因及解決方案記憶體
- SpringMVC請求對映handler原始碼解讀SpringMVC原始碼
- 解決Flutter打包後permission_handler失效問題Flutter
- Android Handler訊息機制原始碼解讀Android原始碼
- 深入瞭解Looper、Handler、Message之間關係OOP
- Handler原理分析
- Handler的原理
- Handler 工作原理
- JAX-WS - 通過xjc命令把Schema生成JavaJava