webservice学习之使用拦截器

时间:2022-12-26 10:08:01
拦截器:    为了能访问、并修改CXF框架所生成的SOAP消息,CXF提供了拦截器,拦截器分为In拦截器和out拦截器,自定拦截器需要实现Imterceptor接口。实际上一般会继承AbstractPhaseInterceptor抽象类,CXF框架本身定义了很多拦截器,很多可以直接使用webservice学习之使用拦截器
1.使用注解实现CXF的拦截器 (1)定义自己的拦截器
package demo.spring.interceptor;



import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;


public class MyInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

public MyInterceptor() {
//因为AbstractPhaseInterceptor没有无参的构造函数,所以子类定义一个构造函数显式调用父类的带参构造函数,
//避免子类隐式调用父类无参构造函数导致错误
super(Phase.PRE_INVOKE);//表示拦截器作用的阶段,在Phase中定义有很多常量表示
// TODO Auto-generated constructor stub
}

@Override
public void handleMessage(SoapMessage arg0) throws Fault {

System.out.println("拦截器添加成功");

}


}
(2)使用@InInterceptors和@OutInterceptors注解将拦截器添加到webservice的业务接口的实现类上面:
package demo.spring.service;

import java.util.HashMap;
import java.util.Map;

import javax.jws.WebService;

import org.apache.cxf.interceptor.InInterceptors;
import org.apache.cxf.interceptor.OutInterceptors;
import org.springframework.stereotype.Component;


@InInterceptors(interceptors = {"demo.spring.interceptor.MyInterceptor", "org.apache.cxf.interceptor.LoggingInInterceptor"})
@OutInterceptors(interceptors = "org.apache.cxf.interceptor.LoggingOutInterceptor")

@Component("hello")
@WebService(endpointInterface = "demo.spring.service.HelloWorld")
public class HelloWorldImpl implements HelloWorld {


public Map<String, String> getSpace(String deviceIp) {
// TODO Auto-generated method stub
HashMap<String, String> test = new HashMap<String,String>();
test.put("test", "10.5");
test.put("ip", deviceIp);

System.out.println("deviceIp: " + deviceIp);

return test;
}
}

org.apache.cxf.interceptor.LoggingInInterceptor,org.apache.cxf.interceptor.LoggingOutInterceptor---CXF自身的日志拦截器,可以打印SOAP消息日志

@InInterceptors和@OutInterceptors的值是一个String字符数组:

org.apache.cxf.interceptor 
Annotation Type InInterceptors


@Target(value=TYPE)
@Retention(value=RUNTIME)
public @interface InInterceptors

Specifies a list of classes that are added to the inbound interceptor chain. This annotation effects SEI classes and service implementation classes.


使用方法在官方文档中实例如下,多个拦截器使用“{}”中间用“,”分离:

You can also use annotation to add the interceptors from the SEI or service class. When CXF create the server or client, CXF will add the interceptor according with the annotation.

@org.apache.cxf.interceptor.InInterceptors (interceptors = {"com.example.Test1Interceptor" })
@org.apache.cxf.interceptor.InFaultInterceptors (interceptors = {"com.example.Test2Interceptor" })
@org.apache.cxf.interceptor.OutInterceptors (interceptors = {"com.example.Test1Interceptor" })
@org.apache.cxf.interceptor.InFaultInterceptors (interceptors = {"com.example.Test2Interceptor","com.example.Test3Intercetpor" })
@WebService(endpointInterface = "org.apache.cxf.javascript.fortest.SimpleDocLitBare",
targetNamespace = "uri:org.apache.cxf.javascript.fortest")
public class SayHiImplementation implements SayHi {
public long sayHi(long arg) {
return arg;
}
...
}

(3)启动tomcat,开启webservice服务,调用客户端,可以看到输出日志如下,拦截器添加成功:
2013-4-9 16:42:55 org.apache.cxf.services.HelloWorldImplService.HelloWorldImplPort.HelloWorld
信息: Inbound Message
----------------------------
ID: 1
Address: http://192.168.1.133:8088/CXFUseCase/services/helloWorld
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[191], content-type=[text/xml; charset=UTF-8], host=[192.168.1.133:8088], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 2.7.1]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getSpace xmlns:ns2="http://service.spring.demo/"><arg0></arg0></ns2:getSpace></soap:Body></soap:Envelope>
--------------------------------------
拦截器添加成功
deviceIp:
2013-4-9 16:42:55 org.apache.cxf.services.HelloWorldImplService.HelloWorldImplPort.HelloWorld
信息: Outbound Message
---------------------------
ID: 1
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getSpaceResponse xmlns:ns2="http://service.spring.demo/"><return><entries><key>test</key><value>10.5</value></entries><entries><key>ip</key><value></value></entries></return></ns2:getSpaceResponse></soap:Body></soap:Envelope>
--------------------------------------
2013-4-9 16:50:00 org.apache.cxf.services.HelloWorldImplService.HelloWorldImplPort.HelloWorld
信息: Inbound Message
----------------------------
ID: 2
Address: http://192.168.1.133:8088/CXFUseCase/services/helloWorld?wsdl
Http-Method: GET
Content-Type:
Headers: {Accept=[application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*], accept-encoding=[gzip, deflate], accept-language=[zh-cn], connection=[Keep-Alive], Content-Type=[null], host=[192.168.1.133:8088], user-agent=[Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3)]}
--------------------------------------
2013-4-9 16:52:20 org.apache.cxf.services.HelloWorldImplService.HelloWorldImplPort.HelloWorld
信息: Inbound Message
----------------------------
ID: 3
Address: http://192.168.1.133:8088/CXFUseCase/services/helloWorld?wsdl
Http-Method: GET
Content-Type:
Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Type=[null], host=[192.168.1.133:8088], user-agent=[Java/1.6.0_25]}
--------------------------------------
2013-4-9 16:53:09 org.apache.cxf.services.HelloWorldImplService.HelloWorldImplPort.HelloWorld
信息: Inbound Message
----------------------------
ID: 4
Address: http://192.168.1.133:8088/CXFUseCase/services/helloWorld?wsdl
Http-Method: GET
Content-Type:
Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Type=[null], host=[192.168.1.133:8088], user-agent=[Java/1.6.0_25]}
--------------------------------------

2.使用spring配置文件实现CXF拦截器,在server端的xml中配置如下,此时webservice业务实现类无需使用注解配置拦截器:
    <jaxws:endpoint id="helloWorld" implementor="#hello" address="/helloWorld">
<jaxws:inInterceptors>
<!-- <ref bean="inLoggeringInterceptor"/>
<ref bean="myInterceptor"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="outLoggingInterceptor"/>
</jaxws:outInterceptors>
</jaxws:endpoint>
<bean id="inLoggeringInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
<bean id="outLoggingInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
<bean id="myInterceptor" class="demo.spring.interceptor.MyInterceptor">
<constructor-arg value="pre-invoke"/>
</bean>