handler能夠做用於客戶端,也能夠做用了服務端java
handler分爲:一、LogicalHandler:只能獲取到soap消息的body。node
二、SOAPHandler:能夠獲取SOAPMessage的信息(咱們一般用這種)。服務器
客戶端--》服務端的請求中經過handler的順序:dom
假如客戶端和服務端的handler-chain.xml中定義的順序都是:LogicalHandler1/SOAPHandler1/LogicalHandler2/SOAPHandler2eclipse
那麼請求的順序將是:ide
client-->LogicalHandler1-->LogicalHandler2-->SOAPHandler1-->SOAPHandler2-->|服務器容器|-->SOAPHandler1-->SOAPHandler2-->LogicalHandler1-->LogicalHandler2-->service測試
1、在客戶端加handlerthis
服務端servicespa
@Override public void testException() throws MyException{ throw new MyException("this is my exception"); }
在classpath目錄下添加handler文件:handler-chain.xmlcode
<?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
.....................
2、服務器端獲取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>