首先下载一个cxf实例,里面包含cxf的jar包。我下的是apache-cxf-2.5.9
1、为什么要设置拦截器?
为了在webservice请求过程中,能动态操作请求和响应数据, CXF设计了拦截器.
2、拦截器分类
1. 按所处的位置分:服务器端拦截器,客户端拦截器
2. 按消息的方向分:入拦截器,出拦截器
3. 按定义者分:系统拦截器,自定义拦截器
3、拦截器API
Interceptor(拦截器接口)
AbstractPhaseInterceptor(自定义拦截器从此继承)
LoggingInInterceptor(系统日志入拦截器类)
LoggingOutInterceptor(系统日志出拦截器类)
4、编写实现拦截器
• 使用日志拦截器,实现日志记录
– LoggingInInterceptor
– LoggingOutInterceptor
• 使用自定义拦截器,实现用户名与密码的检验
– 服务器端的in拦截器
– 客户端的out拦截器
– benjamin/123456
系统日志拦截器代码实现:
Server:
SEI:
- package com.wiseweb.ws;
- import javax.jws.WebMethod;
- import javax.jws.WebService;
- /**
- * SEI
- * @author piqiu
- *
- */
- @WebService
- public interface HelloWS {
- @WebMethod
- public String sayHello(String name) ;
- }
SEI的实现:
- package com.wiseweb.ws;
- import javax.jws.WebService;
- /**
- * SEI的实现
- * @author piqiu
- *
- */
- @WebService
- public class HelloWSImpl implements HelloWS {
- @Override
- public String sayHello(String name) {
- System.out.println("server sayHello():" + name);
- return "Hello: " + name;
- }
- }
ServerTest:
- package com.wiseweb.ws.server;
- import java.util.List;
- import javax.xml.ws.Endpoint;
- import org.apache.cxf.interceptor.Interceptor;
- import org.apache.cxf.interceptor.LoggingInInterceptor;
- import org.apache.cxf.interceptor.LoggingOutInterceptor;
- import org.apache.cxf.jaxws22.EndpointImpl;
- import org.apache.cxf.message.Message;
- import com.wiseweb.ws.HelloWSImpl;
- /**
- * 发布webservice
- * @author piqiu
- *
- */
- public class ServerTest {
- public static void main(String[] args) {
- String address = "http://10.211.55.3:8888/day01_ws/hellows" ;
- Endpoint endpoint = Endpoint.publish(address, new HelloWSImpl()) ;
- EndpointImpl endpointImpl = (EndpointImpl) endpoint ;
- List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInInterceptors() ;
- inInterceptors.add(new LoggingInInterceptor()) ;
- List<Interceptor<? extends Message>> outInterceptors = endpointImpl.getOutInterceptors() ;
- outInterceptors.add(new LoggingOutInterceptor()) ;
- System.out.println("发布webservice成功!");
- }
- }
Client:
把下载下来的apache-cxf-2.5.9的bin目录配置到系统环境变量的path中去,以便可以在cmd中执行bin中的bat文件
在cmd中输入wsdl2java SEI地址就可以生成客户端代码了,同样也可以使用wsimport命令。
项目截图:
ClientTest:
- package com.wiseweb.client;
- import java.util.List;
- import org.apache.cxf.endpoint.Client;
- import org.apache.cxf.frontend.ClientProxy;
- import org.apache.cxf.interceptor.Interceptor;
- import org.apache.cxf.interceptor.LoggingInInterceptor;
- import org.apache.cxf.interceptor.LoggingOutInterceptor;
- import org.apache.cxf.message.Message;
- import com.wiseweb.ws.HelloWS;
- import com.wiseweb.ws.HelloWSImplService;
- public class ClientTest {
- public static void main(String[] args) {
- HelloWSImplService helloWSImplService = new HelloWSImplService() ;
- HelloWS helloWS = helloWSImplService.getHelloWSImplPort() ;
- Client client = ClientProxy.getClient(helloWS) ;
- List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors() ;
- outInterceptors.add(new LoggingOutInterceptor()) ;
- List<Interceptor<? extends Message>> inInterceptors = client.getInInterceptors() ;
- inInterceptors.add(new LoggingInInterceptor()) ;
- String result = helloWS.sayHello("benjaminwhx") ;
- System.out.println(result);
- }
- }
运行结果Server端和Client端比较:
Client:
- 信息: Outbound Message
- ---------------------------
- ID: 1
- Address: http://10.211.55.3:8888/day01_ws/hellows
- Encoding: UTF-8
- Content-Type: text/xml
- Headers: {Accept=[*/*], SOAPAction=[""]}
- Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://ws.wiseweb.com/"><arg0>benjaminwhx</arg0></ns2:sayHello></soap:Body></soap:Envelope>
- --------------------------------------
- 三月 03, 2015 11:03:17 上午 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
- 信息: Inbound Message
- ----------------------------
- ID: 1
- Response-Code: 200
- Encoding: UTF-8
- Content-Type: text/xml;charset=UTF-8
- Headers: {Content-Length=[224], content-type=[text/xml;charset=UTF-8], Server=[Jetty(7.5.4.v20111024)]}
- Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHelloResponse xmlns:ns2="http://ws.wiseweb.com/"><return>Hello: benjaminwhx</return></ns2:sayHelloResponse></soap:Body></soap:Envelope>
- --------------------------------------
- Hello: benjaminwhx
Server:
- 发布webservice成功!
- 三月 03, 2015 11:03:15 上午 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
- 信息: Inbound Message
- ----------------------------
- ID: 1
- Address: http://10.211.55.3:8888/day01_ws/hellows?wsdl
- Encoding: UTF-8
- Http-Method: GET
- Content-Type: text/xml
- Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], content-type=[text/xml], Host=[10.211.55.3:8888], Pragma=[no-cache], User-Agent=[Apache CXF 2.5.9]}
- --------------------------------------
- 三月 03, 2015 11:03:16 上午 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
- 信息: Inbound Message
- ----------------------------
- ID: 2
- Address: http://10.211.55.3:8888/day01_ws/hellows
- Encoding: UTF-8
- Http-Method: POST
- Content-Type: text/xml; charset=UTF-8
- Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[197], content-type=[text/xml; charset=UTF-8], Host=[10.211.55.3:8888], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 2.5.9]}
- Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://ws.wiseweb.com/"><arg0>benjaminwhx</arg0></ns2:sayHello></soap:Body></soap:Envelope>
- --------------------------------------
- server sayHello():benjaminwhx
- 三月 03, 2015 11:03:17 上午 org.apache.cxf.services.HelloWSImplService.HelloWSImplPort.HelloWS
- 信息: Outbound Message
- ---------------------------
- ID: 2
- Encoding: UTF-8
- Content-Type: text/xml
- Headers: {}
- Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHelloResponse xmlns:ns2="http://ws.wiseweb.com/"><return>Hello: benjaminwhx</return></ns2:sayHelloResponse></soap:Body></soap:Envelope>
- --------------------------------------
自定义拦截器代码实现:
Server:
SEI和SEI实现都不做变动,增加一个interceptor:
- package com.wiseweb.ws.interceptor;
- import javax.xml.namespace.QName;
- import org.apache.cxf.binding.soap.SoapMessage;
- import org.apache.cxf.headers.Header;
- import org.apache.cxf.interceptor.Fault;
- import org.apache.cxf.phase.AbstractPhaseInterceptor;
- import org.apache.cxf.phase.Phase;
- import org.w3c.dom.Element;
- public class CheckUserInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
- public CheckUserInterceptor() {
- super(Phase.PRE_PROTOCOL);
- }
- @Override
- public void handleMessage(SoapMessage message) throws Fault {
- Header header = message.getHeader(new QName("wiseweb")) ;
- if(header != null) {
- Element element = (Element)header.getObject() ;
- String username = element.getElementsByTagName("username").item(0).getTextContent() ;
- String password = element.getElementsByTagName("password").item(0).getTextContent() ;
- if(username.equals("benjamin") && password.equals("123456")) {
- System.out.println("用户名与密码正确,通过验证!");
- return ;
- }else {
- throw new Fault(new RuntimeException("请输入正确的用户名和密码!")) ;
- }
- }else {
- throw new Fault(new RuntimeException("请输入用户名和密码!")) ;
- }
- }
- }
ServerTest:
- package com.wiseweb.ws.server;
- import java.util.List;
- import javax.xml.ws.Endpoint;
- import org.apache.cxf.interceptor.Interceptor;
- import org.apache.cxf.jaxws22.EndpointImpl;
- import org.apache.cxf.message.Message;
- import com.wiseweb.ws.HelloWSImpl;
- import com.wiseweb.ws.interceptor.CheckUserInterceptor;
- public class ServetTest2 {
- public static void main(String[] args) {
- String address = "http://10.211.55.3:8888/day01_ws/hellows" ;
- Endpoint endpoint = Endpoint.publish(address, new HelloWSImpl()) ;
- EndpointImpl endpointImpl = (EndpointImpl) endpoint ;
- List<Interceptor<? extends Message>> inInterceptors = endpointImpl.getInInterceptors() ;
- inInterceptors.add(new CheckUserInterceptor()) ;
- System.out.println("发布webservice成功!");
- }
- }
Client:
通过构造方法传入要比较的用户名和密码:
- package com.wiseweb.client.interceptor;
- import java.util.List;
- import javax.xml.namespace.QName;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import javax.xml.parsers.ParserConfigurationException;
- import org.apache.cxf.binding.soap.SoapMessage;
- import org.apache.cxf.headers.Header;
- import org.apache.cxf.interceptor.Fault;
- import org.apache.cxf.phase.AbstractPhaseInterceptor;
- import org.apache.cxf.phase.Phase;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- public class AddUserInterceptor extends AbstractPhaseInterceptor<SoapMessage>{
- private String username ;
- private String password ;
- public AddUserInterceptor(String username, String password) {
- super(Phase.PRE_PROTOCOL);
- this.username = username ;
- this.password = password ;
- }
- @Override
- public void handleMessage(SoapMessage message) throws Fault {
- List<Header> headers = message.getHeaders() ;
- DocumentBuilder builder = null ;
- try {
- builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
- } catch (ParserConfigurationException e) {
- e.printStackTrace();
- }
- Document document = builder.newDocument() ;
- Element root = document.createElement("wiseweb") ;
- Element username = document.createElement("username") ;
- username.setTextContent(this.username);
- Element password = document.createElement("password") ;
- password.setTextContent(this.password);
- root.appendChild(username) ;
- root.appendChild(password) ;
- headers.add(new Header(new QName("wiseweb"), root)) ;
- }
- }
ClientTest:
- package com.wiseweb.client;
- import java.util.List;
- import org.apache.cxf.endpoint.Client;
- import org.apache.cxf.frontend.ClientProxy;
- import org.apache.cxf.interceptor.Interceptor;
- import org.apache.cxf.interceptor.LoggingInInterceptor;
- import org.apache.cxf.interceptor.LoggingOutInterceptor;
- import org.apache.cxf.message.Message;
- import com.wiseweb.client.interceptor.AddUserInterceptor;
- import com.wiseweb.ws.HelloWS;
- import com.wiseweb.ws.HelloWSImplService;
- public class ClientTest2 {
- public static void main(String[] args) {
- HelloWSImplService helloWSImplService = new HelloWSImplService() ;
- HelloWS helloWS = helloWSImplService.getHelloWSImplPort() ;
- Client client = ClientProxy.getClient(helloWS) ;
- List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors() ;
- outInterceptors.add(new AddUserInterceptor("benjamin", "123456")) ;
- String result = helloWS.sayHello("benjaminwhx") ;
- System.out.println(result);
- }
- }
运行结果Server和Client比较:
Server:
- 发布webservice成功!
- 用户名与密码正确,通过验证!
- server sayHello():benjaminwhx
- Hello: benjaminwhx
如果输入的用户名和密码不正确,运行结果为:
Server:
- org.apache.cxf.interceptor.Fault: 请输入正确的用户名和密码!
- at com.wiseweb.ws.interceptor.CheckUserInterceptor.handleMessage(CheckUserInterceptor.java:29)
- at com.wiseweb.ws.interceptor.CheckUserInterceptor.handleMessage(CheckUserInterceptor.java:1)
- at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
- at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:122)
- at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.serviceRequest(JettyHTTPDestination.java:348)
- at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:312)
- at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:72)
- at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:943)
- at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:879)
- at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
- at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:250)
- at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:110)
- at org.eclipse.jetty.server.Server.handle(Server.java:349)
- at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:441)
- at org.eclipse.jetty.server.HttpConnection$RequestHandler.content(HttpConnection.java:936)
- at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:801)
- at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:224)
- at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:51)
- at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:586)
- at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:44)
- at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:598)
- at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:533)
- at java.lang.Thread.run(Thread.java:745)
- Caused by: java.lang.RuntimeException: 请输入正确的用户名和密码!
- ... 23 more
Client:
- Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: 请输入正确的用户名和密码!
- at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)
- at com.sun.proxy.$Proxy25.sayHello(Unknown Source)
- at com.wiseweb.client.ClientTest2.main(ClientTest2.java:26)
- Caused by: org.apache.cxf.binding.soap.SoapFault: 请输入正确的用户名和密码!
- at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:75)
- at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:46)
- at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.handleMessage(Soap11FaultInInterceptor.java:35)
- at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
- at org.apache.cxf.interceptor.AbstractFaultChainInitiatorObserver.onMessage(AbstractFaultChainInitiatorObserver.java:114)
- at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:69)
- at org.apache.cxf.binding.soap.interceptor.CheckFaultInterceptor.handleMessage(CheckFaultInterceptor.java:34)
- at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
- at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:801)
- at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1679)
- at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1517)
- at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1425)
- at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
- at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:650)
- at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
- at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
- at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
- at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:462)
- at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:365)
- at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:318)
- at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:95)
- at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
- ... 2 more
这样就可以有效的验证访客的身份。