拦截器是Cxf的基础,Cxf中很多的功能都是由内置的拦截器来实现的,拦截器在Cxf中由Interceptor表示。拦截器的作用类似axis2中handle。Cxf的拦截器包括入拦截器和出拦截器,所有的入拦截器或出拦截器构成了一个拦截器链,它们可以作用在Server端也可以作用在Client端。当需要使用拦截器链处理消息的时候,Cxf会确保对应的消息被拦截器链里面的每一个拦截器都执行一遍。拦截器链在Cxf中由InterceptorChain接口表示,org.apache.cxf.phase.PhaseInterceptorChain类的public synchronized boolean doIntercept(Message message)方法,它是拦截器链拦截Message的实现。当客户端发送一个请求到服务端时会经过客户端的出拦截器和服务端的入拦截器;当服务端对客户端的请求进行响应时对应的响应消息会经过服务端的出拦截器和客户端的入拦截器。
下面简单介绍一下服务端拦截器,在上一篇工程基础上进行如下修改:
在服务端应用里面,增加一个类,这个类继承自AbstractPhaseInterceptor。
package com.myl.interceptor; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; /** * * @author myl * @date 2018年4月18日 上午12:10:20 * * 拦截器,继承AbstractPhaseInterceptor<Message> */ public class WsInterceptor extends AbstractPhaseInterceptor<Message> { public WsInterceptor(String phase) { super(phase); // TODO Auto-generated constructor stub } @Override public void handleMessage(Message message) throws Fault { // TODO Auto-generated method stub System.out.println("-------into Interceptor-------"); System.out.println(message); if(message.getDestination() != null){ System.out.println(message.getId() + "-" + message.getDestination().getMessageObserver()); } if(message.getExchange() != null){ System.out.println(message.getId() + "#" + message.getExchange().getInFaultMessage()); System.out.println(message.getId() + "#" + message.getExchange().getOutFaultMessage()); } System.out.println("-------out Interceptor-------"); } }
修改服务发布,注意下面加粗斜体的地方
package com.myl.test.publish; import org.apache.cxf.endpoint.Server; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; import org.apache.cxf.phase.Phase; import com.myl.interceptor.WsInterceptor; import com.myl.service.serviceImpl.StudentWsImpl; /** * * @author myl * @date 2018年4月15日 下午11:26:50 * 服务端发布接口 */ public class StudentTest { public static void main(String[] args) { System.out.println("web service start"); //获取工厂对象 JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean(); //这里必须传入class,不能是接口,否则客户端会报异常 Could not instantiate service class ... because it is an interface factory.setServiceClass(StudentWsImpl.class); //传入接口url factory.setAddress("http://localhost:5555/studentws"); //往入拦截器链中添加拦截器 factory.getInInterceptors().add(new WsInterceptor(Phase.RECEIVE)); //往出拦截器链中添加拦截器 factory.getOutInterceptors().add(new WsInterceptor(Phase.SEND)); //创建接口 Server server = factory.create(); //启动接口 server.start(); System.out.println("web service started"); } }
启动服务后,当客户端调用服务端接口的时候,我们可以看到拦截器发挥作用,日志如下:
-------into Interceptor-------
{http.base.path=http://localhost:5555, HTTP.REQUEST=Request(POST /studentws?wsdl)@4b47c90, org.apache.cxf.transport.Destination=org.apache.cxf.transport.http_jetty.JettyHTTPDestination@4561dae, HTTP.CONFIG=null, org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@6da4eb38, org.apache.cxf.message.Message.QUERY_STRING=wsdl, org.apache.cxf.message.Message.ENCODING=UTF-8, HTTP.CONTEXT=ServletContext@o.e.j.s.h.ContextHandler@5082d622{/,null,AVAILABLE}, Content-Type=text/xml; charset=UTF-8, org.apache.cxf.security.SecurityContext=org.apache.cxf.transport.http.AbstractHTTPDestination$2@12c06064, org.apache.cxf.continuations.ContinuationProvider=org.apache.cxf.transport.http.Servlet3ContinuationProvider@188a71a, org.apache.cxf.message.Message.PROTOCOL_HEADERS={Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[250], content-type=[text/xml; charset=UTF-8], Host=[localhost:5555], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache-CXF/3.1.15]}, org.apache.cxf.request.url=http://localhost:5555/studentws, Accept=*/*, org.apache.cxf.request.uri=/studentws, org.apache.cxf.message.Message.PATH_INFO=/studentws, org.apache.cxf.transport.https.CertConstraints=null, HTTP.RESPONSE=HTTP/1.1 200
Date: Tue, 17 Apr 2018 16:24:13 GMT
, org.apache.cxf.request.method=POST, org.apache.cxf.async.post.response.dispatch=true, org.apache.cxf.message.Message.IN_INTERCEPTORS=[org.apache.cxf.transport.https.CertConstraintsInterceptor@fd5a77f], HTTP_CONTEXT_MATCH_STRATEGY=stem, http.service.redirection=null, org.apache.cxf.message.Message.BASE_PATH=/studentws, org.apache.cxf.configuration.security.AuthorizationPolicy=null, org.apache.cxf.message.Message.FIXED_PARAMETER_ORDER=false}
null-org.apache.cxf.transport.ChainInitiationObserver@45e27096
null#null
null#null
-------out Interceptor-------
addStudent-------------
student是否为空--com.myl.entity.Student@490b0e79
ya
-------into Interceptor-------
{org.apache.cxf.message.Message.PROTOCOL_HEADERS={}, http.headers.copied=true, org.apache.cxf.service.model.MessageInfo=[MessageInfo OUTPUT: {http://serviceImpl.service.myl.com/}addStudentServiceResponse], org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@6da4eb38, javax.xml.ws.wsdl.operation={http://serviceImpl.service.myl.com/}addStudentService, javax.xml.ws.wsdl.service={http://serviceImpl.service.myl.com/}StudentWsImplService, HTTP.RESPONSE=HTTP/1.1 200
Date: Tue, 17 Apr 2018 16:24:13 GMT
Content-Type: text/xml; charset=UTF-8
, org.apache.cxf.headers.Header.list=[], schema-validation-enabled=NONE, wrote.envelope.start=true, org.apache.cxf.service.model.BindingMessageInfo=org.apache.cxf.service.model.BindingMessageInfo@1603131c, javax.xml.ws.wsdl.port={http://serviceImpl.service.myl.com/}StudentWsImplPort, javax.xml.ws.wsdl.interface={http://serviceImpl.service.myl.com/}StudentWsImpl, javax.xml.ws.wsdl.description=http://localhost:5555/studentws?wsdl, org.apache.cxf.mime.headers={}, org.apache.cxf.message.Message.ENCODING=UTF-8, org.apache.cxf.ws.policy.EffectivePolicy=org.apache.cxf.ws.policy.EffectivePolicyImpl@2d1abacf, org.apache.cxf.message.Message.RESPONSE_CODE=200, Content-Type=text/xml}
null#null
null#null
-------out Interceptor-------
省略部分....
客户端可以跟服务端类似写,我测试直接用的一样的
package com.interceptor; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; /** * * @author myl * @date 2018年4月18日 上午12:10:20 * * 客户端 拦截器,继承AbstractPhaseInterceptor<Message> */ public class WsInterceptor extends AbstractPhaseInterceptor<Message> { public WsInterceptor(String phase) { super(phase); // TODO Auto-generated constructor stub } @Override public void handleMessage(Message message) throws Fault { // TODO Auto-generated method stub System.out.println("-------into Interceptor Client-------"); System.out.println(message); if(message.getDestination() != null){ System.out.println(message.getId() + "-" + message.getDestination().getMessageObserver()); } if(message.getExchange() != null){ System.out.println(message.getId() + "#" + message.getExchange().getInFaultMessage()); System.out.println(message.getId() + "#" + message.getExchange().getOutFaultMessage()); } System.out.println("-------out Interceptor Client-------"); } }
客户端调用接口
package com.client; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.apache.cxf.phase.Phase; import com.interceptor.WsInterceptor; import com.webservice.StudentWsImpl; /** * @author myl * @date 2018年4月15日 * 客户端调用服务端发布的接口 */ public class StudentSerivceTest { public static void main(String[] args) { //获取工厂对象 JaxWsProxyFactoryBean jwpfb = new JaxWsProxyFactoryBean(); //加载生成的StudentWsImpl类 jwpfb.setServiceClass(StudentWsImpl.class); //传入url接口地址 jwpfb.setAddress("http://localhost:5555/studentws?wsdl"); //往入拦截器链中添加拦截器 jwpfb.getInInterceptors().add(new WsInterceptor(Phase.RECEIVE)); //往出拦截器链中添加拦截器 jwpfb.getOutInterceptors().add(new WsInterceptor(Phase.SEND)); //创建接口对象 StudentWsImpl ws = (StudentWsImpl) jwpfb.create(); //调用接口中的方法 ws.addStudentService("mao", "11", "22"); ws.addStudentService("ya", "15", "23"); ws.queryStudentService("mao"); ws.queryStudentService("ya"); } }
客户端日志
-------into Interceptor Client-------
{org.apache.cxf.message.Message.PROTOCOL_HEADERS={Accept=[*/*], SOAPAction=[""]}, org.apache.cxf.transport.Conduit=conduit: class org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit57241990target: http://localhost:5555/studentws?wsdl, use.async.http.conduit=false, org.apache.cxf.service.model.MessageInfo=[MessageInfo INPUT: {http://serviceImpl.service.myl.com/}addStudentService], org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@1583741e, org.apache.cxf.message.Message.ENDPOINT_ADDRESS=http://localhost:5555/studentws?wsdl, org.apache.cxf.headers.Header.list=[], schema-validation-enabled=NONE, org.apache.cxf.request.method=POST, http.connection.address=org.apache.cxf.transport.http.Address@5b367418, wrote.envelope.start=true, http.connection=sun.net.www.protocol.http.HttpURLConnection:http://localhost:5555/studentws?wsdl, org.apache.cxf.service.model.BindingMessageInfo=org.apache.cxf.service.model.BindingMessageInfo@36060e, org.apache.cxf.invocation.context={ResponseContext={}, RequestContext={org.apache.cxf.jaxws.context.WrappedMessageContext.SCOPES={org.apache.cxf.message.Message.ENDPOINT_ADDRESS=APPLICATION}, org.apache.cxf.message.Message.ENDPOINT_ADDRESS=http://localhost:5555/studentws?wsdl, java.lang.reflect.Method=public abstract boolean com.webservice.StudentWsImpl.addStudentService(java.lang.String,java.lang.String,java.lang.String)}}, org.apache.cxf.client=true, client.holders=[null, null, null], org.apache.cxf.jaxws.context.WrappedMessageContext.SCOPES={org.apache.cxf.message.Message.ENDPOINT_ADDRESS=APPLICATION}, org.apache.cxf.mime.headers={}, org.apache.cxf.message.inbound=false, org.apache.cxf.message.Message.ENCODING=UTF-8, org.apache.cxf.ws.policy.EffectivePolicy=org.apache.cxf.ws.policy.EffectivePolicyImpl@481ba2cf, java.lang.reflect.Method=public abstract boolean com.webservice.StudentWsImpl.addStudentService(java.lang.String,java.lang.String,java.lang.String), http.scheme=http, Content-Type=text/xml}
null#null
null#null
-------out Interceptor Client-------
-------into Interceptor Client-------
{org.apache.cxf.message.Message.PROTOCOL_HEADERS={Content-Length=[241], content-type=[text/xml; charset=UTF-8], Date=[Tue, 17 Apr 2018 16:39:14 GMT], Server=[Jetty(9.2.22.v20170606)]}, org.apache.cxf.ws.policy.AssertionInfoMap={}, org.apache.cxf.transport.Conduit=conduit: class org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit57241990target: http://localhost:5555/studentws?wsdl, org.apache.cxf.client=true, org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@1583741e, org.apache.cxf.message.Message.ENCODING=UTF-8, org.apache.cxf.message.inbound=true, org.apache.cxf.message.Message.RESPONSE_CODE=200, Content-Type=text/xml; charset=UTF-8}
null#null
null#null
-------out Interceptor Client-------
-------into Interceptor Client-------
{org.apache.cxf.message.Message.PROTOCOL_HEADERS={Accept=[*/*], SOAPAction=[""]}, org.apache.cxf.transport.Conduit=conduit: class org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit57241990target: http://localhost:5555/studentws?wsdl, use.async.http.conduit=false, org.apache.cxf.service.model.MessageInfo=[MessageInfo INPUT: {http://serviceImpl.service.myl.com/}addStudentService], org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@1583741e, org.apache.cxf.message.Message.ENDPOINT_ADDRESS=http://localhost:5555/studentws?wsdl, org.apache.cxf.headers.Header.list=[], schema-validation-enabled=NONE, org.apache.cxf.request.method=POST, http.connection.address=org.apache.cxf.transport.http.Address@5b367418, wrote.envelope.start=true, http.connection=sun.net.www.protocol.http.HttpURLConnection:http://localhost:5555/studentws?wsdl, org.apache.cxf.service.model.BindingMessageInfo=org.apache.cxf.service.model.BindingMessageInfo@36060e, org.apache.cxf.invocation.context={ResponseContext={}, RequestContext={org.apache.cxf.jaxws.context.WrappedMessageContext.SCOPES={org.apache.cxf.message.Message.ENDPOINT_ADDRESS=APPLICATION}, org.apache.cxf.message.Message.ENDPOINT_ADDRESS=http://localhost:5555/studentws?wsdl, java.lang.reflect.Method=public abstract boolean com.webservice.StudentWsImpl.addStudentService(java.lang.String,java.lang.String,java.lang.String)}}, org.apache.cxf.client=true, client.holders=[null, null, null], org.apache.cxf.jaxws.context.WrappedMessageContext.SCOPES={org.apache.cxf.message.Message.ENDPOINT_ADDRESS=APPLICATION}, org.apache.cxf.mime.headers={}, org.apache.cxf.message.inbound=false, org.apache.cxf.message.Message.ENCODING=UTF-8, org.apache.cxf.ws.policy.EffectivePolicy=org.apache.cxf.ws.policy.EffectivePolicyImpl@481ba2cf, java.lang.reflect.Method=public abstract boolean com.webservice.StudentWsImpl.addStudentService(java.lang.String,java.lang.String,java.lang.String), http.scheme=http, Content-Type=text/xml}
null#null
null#null
-------out Interceptor Client-------
-------into Interceptor Client-------
{org.apache.cxf.message.Message.PROTOCOL_HEADERS={Content-Length=[241], content-type=[text/xml; charset=UTF-8], Date=[Tue, 17 Apr 2018 16:39:14 GMT], Server=[Jetty(9.2.22.v20170606)]}, org.apache.cxf.ws.policy.AssertionInfoMap={}, org.apache.cxf.transport.Conduit=conduit: class org.apache.cxf.transport.http.asyncclient.AsyncHTTPConduit57241990target: http://localhost:5555/studentws?wsdl, org.apache.cxf.client=true, org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap11@1583741e, org.apache.cxf.message.Message.ENCODING=UTF-8, org.apache.cxf.message.inbound=true, org.apache.cxf.message.Message.RESPONSE_CODE=200, Content-Type=text/xml; charset=UTF-8}
null#null
null#null
-------out Interceptor Client-------
简单测试,如有错误请多指点