您的位置:首页 > 其它

WebServices中使用cxf开发日志拦截器以及自定义拦截器

2015-03-03 11:11 603 查看
首先下载一个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

Client:
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


这样就可以有效的验证访客的身份。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  WebService
相关文章推荐