JAX-WS的Handler和Servlet的Filter相似,可以对所有WebServicer进行拦截,在Handler中可以记录日志、权限控制、对请求的SOAP消息进行加密,解密等。JAX-WS提供两个Handler接口,LogicalHandler和SOAPHandler。LogicalHandler处理的是Message Payload,只能够访问消息单元中的SOAP消息体。SOAPHandler处理的是整个SOAP消息(包含SOAP header和SOAP body),可以访问整个SOAP消息。
注册Handler的方式有下面几种:
使用HandlerResolver(客户端比较方便)
使用HandlerChain注解和配置文件
从WSDL生成
使用Custom Binding声明HandlerChain
实例代码http://download.csdn.net/detail/accountwcx/8922191
JAX-WS中WebService执行顺序如图所示
下面用SOAPHandler实现在WebService服务端记录请求内容和响应内容。
import java.io.IOException; import java.util.Set; import javax.xml.namespace.QName; import javax.xml.soap.SOAPException; 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; /** * 记录SOAP请求及响应 * @author [email protected] * */ public class LoggerHandler implements SOAPHandler<SOAPMessageContext> { @Override public void close(MessageContext context) { } @Override public boolean handleFault(SOAPMessageContext context) { return true; } @Override public boolean handleMessage(SOAPMessageContext context) { // 判断消息是输入还是输出 Boolean output = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); System.out.println(output ? "响应SOAP:" : "请求SOAP:"); SOAPMessage message = context.getMessage(); try { message.writeTo(System.out); } catch (SOAPException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println(""); return true; } @Override public Set<QName> getHeaders() { return null; } }
<?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.rvho.server.ws.handler.LoggerHandler</javaee:handler-class> </javaee:handler> </javaee:handler-chain> </javaee:handler-chains>
package com.rvho.server.ws.impl; import java.util.Date; import javax.jws.HandlerChain; import javax.jws.WebService; import com.rvho.server.ws.HelloWService; @WebService( endpointInterface = "com.rvho.server.ws.HelloWService", portName = "HelloWSPort", serviceName = "HelloWSService", targetNamespace = "http://www.tmp.com/ws/hello" ) @HandlerChain(file="handler-chain.xml") //添加Handler配置文件 public class HelloWServiceImpl implements HelloWService { public String index() { return "hello"; } public Integer add(Integer x, Integer y) { return x + y; } public Date now() { return new Date(); } }
package com.rvho.server.ws; import java.util.Date; import javax.jws.WebService; /** * WebService接口 */ @WebService( name = "HelloWS", targetNamespace = "http://www.tmp.com/ws/hello" ) public interface HelloWService { /** * 返回字符串 * * @return */ String index(); /** * 两个整数相加 * * @param x * @param y * @return 相加后的值 */ Integer add(Integer x, Integer y); /** * 返回当前时间 * * @return */ Date now(); }
请求SOAP: <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <S:Body> <ns2:index xmlns:ns2="http://www.tmp.com/ws/hello" /> </S:Body> </S:Envelope> 响应SOAP: <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <S:Body> <ns2:indexResponse xmlns:ns2="http://www.tmp.com/ws/hello"> <return>hello</return> </ns2:indexResponse> </S:Body> </S:Envelope>