webservice系统学习笔记7-使用handler实现过滤器/拦截器效果
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>