WebServices中使用cxf开发日志拦截器以及自定义拦截器
首先下载一个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
这样就可以有效的验证访客的身份。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。