天天看點

CXF對Interceptor攔截器的支援

在Axis中Axis的Handler,這裡CXF的Interceptor就和Handler的功能類似。在每個請求響應之前或響應之後,做一些事情。這裡的Interceptor就和Filter、Struts的Interceptor很類似,提供它的主要作用就是為了很好的降低代碼的耦合性,提供代碼的内聚性。下面我們就看看CXF的Interceptor是怎麼樣工作的。

1.

package com.hoo.client;      
import org.apache.cxf.interceptor.LoggingInInterceptor;      
import org.apache.cxf.interceptor.LoggingOutInterceptor;      
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;      
import org.apache.cxf.phase.Phase;      
import com.hoo.interceptor.MessageInterceptor;      
import com.hoo.service.IHelloWorldService;      
/**      
* <b>function:</b>CXF WebService用戶端調用代碼      
* @author hoojo      
* @createDate 2011-3-16 上午09:03:49      
* @file HelloWorldServiceClient.java      
* @package com.hoo.client      
* @project CXFWebService      
* @blog http://blog.csdn.net/IBM_hoojo      
* @email [email protected]      
* @version 1.0      
*/      
public class ServiceMessageInterceperClient {      
public static void main(String[] args) {      
//調用WebService      
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();      
factory.setServiceClass(IHelloWorldService.class);      
factory.setAddress("http://localhost:9000/helloWorld");      
factory.getInInterceptors().add(new LoggingInInterceptor());      
factory.getOutInterceptors().add(new LoggingOutInterceptor());      
IHelloWorldService service = (IHelloWorldService) factory.create();      
System.out.println("[result]" + service.sayHello("hoojo"));      
}      
}      

上面的CXF的攔截器是添加在用戶端,同樣在伺服器端也是可以添加攔截器Interceptor的。運作後結果如下:

2011-3-18 7:34:00 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
資訊: Creating Service {http://service.hoo.com/}IHelloWorldServiceService from class com.hoo.service.IHelloWorldService
2011-3-18 7:34:00 org.apache.cxf.interceptor.AbstractLoggingInterceptor log
資訊: Outbound Message
---------------------------
ID: 1
Address: http://localhost:9000/helloWorld
Encoding: UTF-8
Content-Type: text/xml
Headers: {SOAPAction=[""], Accept=[*/*]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:sayHello xmlns:ns1="http://service.hoo.com/"><name>hoojo</name></ns1:sayHello></soap:Body></soap:Envelope>
--------------------------------------
2011-3-18 7:34:01 org.apache.cxf.interceptor.AbstractLoggingInterceptor log
資訊: Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml;charset=UTF-8
Headers: {content-type=[text/xml;charset=UTF-8], Content-Length=[230], Server=[Jetty(7.2.2.v20101205)]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:sayHelloResponse xmlns:ns1="http://service.hoo.com/"><return>hoojo say: Hello World </return></ns1:sayHelloResponse></soap:Body></soap:Envelope>
--------------------------------------
[result]hoojo say: Hello World       

上面的部分資訊是LoggingInterceptor輸出的日志資訊,分别在請求和響應的時候輸出日志資訊,還有輸出請求的時候參數的資訊以及響應的時候傳回值的資訊。

2、 剛才是用戶端添加Interceptor,現在我們自己編寫一個Interceptor,這個Interceptor需要繼承AbstractPhaseInterceptor,實作handleMessage和一個帶參數的構造函數。然後在伺服器端添加這個Interceptor。

Interceptor代碼如下:

package com.hoo.interceptor;      
import org.apache.cxf.interceptor.Fault;      
import org.apache.cxf.message.Message;      
import org.apache.cxf.phase.AbstractPhaseInterceptor;      
/**      
* <b>function:</b> 自定義消息攔截器      
* @author hoojo      
* @createDate Mar 17, 2011 8:10:49 PM      
* @file MessageInterceptor.java      
* @package com.hoo.interceptor      
* @project CXFWebService      
* @blog http://blog.csdn.net/IBM_hoojo      
* @email [email protected]      
* @version 1.0      
*/      
public class MessageInterceptor extends AbstractPhaseInterceptor<Message> {      
//至少要一個帶參的構造函數      
public MessageInterceptor(String phase) {      
super(phase);      
}      
public void handleMessage(Message message) throws Fault {      
System.out.println("############handleMessage##########");      
System.out.println(message);      
if (message.getDestination() != null) {      
System.out.println(message.getId() + "#" + message.getDestination().getMessageObserver());      
}      
if (message.getExchange() != null) {      
System.out.println(message.getExchange().getInMessage() + "#" + message.getExchange().getInFaultMessage());      
System.out.println(message.getExchange().getOutMessage() + "#" + message.getExchange().getOutFaultMessage());      
}      
}      
}      

下面看看釋出服務和添加自定義攔截器的代碼:

package com.hoo.service.deploy;      
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;      
import org.apache.cxf.phase.Phase;      
import com.hoo.interceptor.MessageInterceptor;      
import com.hoo.service.HelloWorldService;      
/**      
* <b>function:</b>在伺服器釋出自定義的Interceptor      
* @author hoojo      
* @createDate 2011-3-18 上午07:38:28      
* @file DeployInterceptorService.java      
* @package com.hoo.service.deploy      
* @project CXFWebService      
* @blog http://blog.csdn.net/IBM_hoojo      
* @email [email protected]      
* @version 1.0      
*/      
public class DeployInterceptorService {      
public static void main(String[] args) throws InterruptedException {      
//釋出WebService      
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();      
//設定Service Class      
factory.setServiceClass(HelloWorldService.class);      
factory.setAddress("http://localhost:9000/helloWorld");      
//設定ServiceBean對象      
factory.setServiceBean(new HelloWorldService());      
//添加請求和響應的攔截器,Phase.RECEIVE隻對In有效,Phase.SEND隻對Out有效      
factory.getInInterceptors().add(new MessageInterceptor(Phase.RECEIVE));      
factory.getOutInterceptors().add(new MessageInterceptor(Phase.SEND));      
factory.create();      
System.out.println("Server start ......");      
Thread.sleep(1000 * 60);      
System.exit(0);      
System.out.println("Server exit ");      
}      
}      

值得說的是,以前釋出WebService是用Endpoint的push方法。這裡用的是JaxWsServerFactoryBean和用戶端調用的代碼JaxWsProxyFactoryBean有點不同。

用戶端調用代碼:

package com.hoo.client;      
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;      
import com.hoo.service.IHelloWorldService;      
/**      
* <b>function:</b>CXF WebService用戶端調用代碼      
* @author hoojo      
* @createDate 2011-3-16 上午09:03:49      
* @file HelloWorldServiceClient.java      
* @package com.hoo.client      
* @project CXFWebService      
* @blog http://blog.csdn.net/IBM_hoojo      
* @email [email protected]      
* @version 1.0      
*/      
public class HelloWorldServiceClient {      
public static void main(String[] args) {      
//調用WebService      
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();      
factory.setServiceClass(IHelloWorldService.class);      
factory.setAddress("http://localhost:9000/helloWorld");      
IHelloWorldService service = (IHelloWorldService) factory.create();      
System.out.println("[result]" + service.sayHello("hoojo"));      
}      
}