handler可以作用於客戶端,也可以作用了服務端
handler分為:1、LogicalHandler:只能獲取到soap消息的body。
2、SOAPHandler:可以獲取SOAPMessage的信息(我們通常用這種)。
客戶端--》服務端的請求中通過handler的順序:
假如客戶端和服務端的handler-chain.xml中定義的順序都是:LogicalHandler1/SOAPHandler1/LogicalHandler2/SOAPHandler2
那么請求的順序將是:
client-->LogicalHandler1-->LogicalHandler2-->SOAPHandler1-->SOAPHandler2-->|服務器容器|-->SOAPHandler1-->SOAPHandler2-->LogicalHandler1-->LogicalHandler2-->service
一、在客戶端加handler
服務端service
@Override public void testException() throws MyException{ throw new MyException("this is my exception"); }
在classpath目錄下添加handler文件:handler-chain.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <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.ws03.MySoapHandler</javaee:handler-class> </javaee:handler> <!--還可以加入其它的handler <javaee:handler> <javaee:handler-class>com.ws03.MySoapHandler</javaee:handler-class> </javaee:handler> --> </javaee:handler-chain> </javaee:handler-chains>
MySoapHandler.java
package com.ws03; import java.io.IOException; 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.SOAPMessage; import javax.xml.ws.handler.MessageContext; import javax.xml.ws.handler.soap.SOAPHandler; import javax.xml.ws.handler.soap.SOAPMessageContext; public class MySoapHandler implements SOAPHandler<SOAPMessageContext> { @Override public boolean handleFault(SOAPMessageContext context) { System.out.println("run handleFault method!"); return false; } /** * 先判斷是否是發出去的消息,然后再在soapheader中添加消息userpassword */ @Override public boolean handleMessage(SOAPMessageContext context) { System.out.println("run handleMessage method!"); Boolean out = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if(out){ SOAPMessage message = context.getMessage(); try { SOAPEnvelope senv = message.getSOAPPart().getEnvelope(); SOAPHeader header = senv.getHeader(); if(header==null){ header = senv.addHeader(); } QName qname = new QName("http://ws01.com/", "userpassword","lic"); header.addChildElement(qname).setValue("123456"); message.writeTo(System.out); System.out.println(); } catch (SOAPException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
//返回true表示繼續執行之后的業務代碼,否則停止運行業務代碼 return true; } @Override public void close(MessageContext context) { System.out.println("run close method!"); } @Override public Set<QName> getHeaders() { return null; } }
使用wsimport命令或者myeclipse生成客戶端代碼:
修改生成的IServiceImpService.java文件,在類定義上加上下面注解:
@HandlerChain(file="handler-chain.xml")
測試類:
@Test public void test01(){ IServiceImpService service = new IServiceImpService(); IService iService = service.getIServiceImpPort(); try { iService.testException(); } catch (MyException_Exception e) { e.printStackTrace(); } }
運行結果:
run handleMessage method! <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Header><lic:userpassword xmlns:lic="http://ws01.com/">123456</lic:userpassword></S:Header><S:Body><ns2:testException xmlns:ns2="http://ws01.com/"/></S:Body></S:Envelope> run handleFault method! run close method! com.ws03.MyException_Exception: test exception
.....................
二、服務器端獲取soapheader消息
編寫服務端handler的java文件,並配置。
ServiceSoapHandler.java
package com.ws01; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPHeader; 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; import org.w3c.dom.Node; public class ServiceSoapHandler implements SOAPHandler<SOAPMessageContext> { /** * 如果客戶端的saopheader為空或者密碼不能123456則直接停止運行業務代碼 */ @Override public boolean handleMessage(SOAPMessageContext context) { Boolean out = (Boolean)context.get(SOAPMessageContext.MESSAGE_OUTBOUND_PROPERTY); if(!out){ SOAPMessage message = context.getMessage(); try { SOAPHeader header = message.getSOAPPart().getEnvelope().getHeader(); if(header != null){ Node node = header.getElementsByTagName("lic:userpassword").item(0); String password = node.getTextContent(); System.out.println("client send password:"+password); if(!"123456".equals(password)) return false; }else{ return false; } } catch (SOAPException e) { e.printStackTrace(); } } return true; } @Override public Set<QName> getHeaders() { // TODO Auto-generated method stub return null; } @Override public void close(MessageContext context) { // TODO Auto-generated method stub } @Override public boolean handleFault(SOAPMessageContext context) { // TODO Auto-generated method stub return false; } }
IServiceImp.java
package com.ws01; import javax.jws.HandlerChain; import javax.jws.WebService; @WebService(endpointInterface="com.ws01.IService") @HandlerChain(file="service-handler-chain.xml") public class IServiceImp implements IService { @Override public void testException() throws MyException { throw new MyException("test exception"); //throw new RuntimeException("service runtime Exception"); } }
service-handler-chain.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <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.ws01.ServiceSoapHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>