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 accountwcx@qq.com
- *
- */
- 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;
- }
- }
在classpath下建handler-chain.xml配置文件
- <?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>
在服务实现类上添加HandlerChain配置
- 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();
- }
客户端发起index请求,服务端的记录
- 请求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>