天天看點

WebServices中使用cxf開發日志攔截器以及自定義攔截器

首先下載下傳一個cxf執行個體,裡面包含cxf的jar包。我下的是apache-cxf-2.5.9

1、為什麼要設定攔截器?

為了在webservice請求過程中,能動态操作請求和響應資料, cxf設計了攔截器.

2、攔截器分類

1. 按所處的位置分:伺服器端攔截器,用戶端攔截器

2. 按消息的方向分:入攔截器,出攔截器

3. 按定義者分:系統攔截器,自定義攔截器

WebServices中使用cxf開發日志攔截器以及自定義攔截器

3、攔截器api

interceptor(攔截器接口)

abstractphaseinterceptor(自定義攔截器從此繼承)

loggingininterceptor(系統日志入攔截器類)

loggingoutinterceptor(系統日志出攔截器類)

WebServices中使用cxf開發日志攔截器以及自定義攔截器

4、編寫實作攔截器

• 使用日志攔截器,實作日志記錄

– loggingininterceptor

– loggingoutinterceptor

• 使用自定義攔截器,實作使用者名與密碼的檢驗

– 伺服器端的in攔截器

– 用戶端的out攔截器

– benjamin/123456

系統日志攔截器代碼實作:

server:

sei:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

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的實作:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

 * sei的實作  

public class hellowsimpl implements hellows {  

    @override  

    public string sayhello(string name) {  

        system.out.println("server sayhello():" + name);  

        return "hello: " + name;  

    }  

servertest:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

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  

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檔案

WebServices中使用cxf開發日志攔截器以及自定義攔截器

在cmd中輸入wsdl2java sei位址就可以生成用戶端代碼了,同樣也可以使用wsimport指令。

項目截圖:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

clienttest:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

package com.wiseweb.client;  

import org.apache.cxf.endpoint.client;  

import org.apache.cxf.frontend.clientproxy;  

import com.wiseweb.ws.hellows;  

import com.wiseweb.ws.hellowsimplservice;  

public class clienttest {  

        hellowsimplservice hellowsimplservice = new hellowsimplservice() ;  

        hellows hellows = hellowsimplservice.gethellowsimplport() ;  

        client client = clientproxy.getclient(hellows) ;  

        list<interceptor<? extends message>> outinterceptors = client.getoutinterceptors() ;  

        list<interceptor<? extends message>> ininterceptors = client.getininterceptors() ;  

        string result = hellows.sayhello("benjaminwhx") ;  

        system.out.println(result);  

運作結果server端和client端比較:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

資訊: 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  

----------------------------  

response-code: 200  

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  

WebServices中使用cxf開發日志攔截器以及自定義攔截器

釋出webservice成功!  

三月 03, 2015 11:03:15 上午 org.apache.cxf.services.hellowsimplservice.hellowsimplport.hellows  

address: http://10.211.55.3:8888/day01_ws/hellows?wsdl  

http-method: get  

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  

id: 2  

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]}  

server sayhello():benjaminwhx  

headers: {}  

自定義攔截器代碼實作:

sei和sei實作都不做變動,增加一個interceptor:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

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);  

    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("請輸入使用者名和密碼!")) ;  

        }  

WebServices中使用cxf開發日志攔截器以及自定義攔截器

import com.wiseweb.ws.interceptor.checkuserinterceptor;  

public class servettest2 {  

        ininterceptors.add(new checkuserinterceptor()) ;  

通過構造方法傳入要比較的使用者名和密碼:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

package com.wiseweb.client.interceptor;  

import javax.xml.parsers.documentbuilder;  

import javax.xml.parsers.documentbuilderfactory;  

import javax.xml.parsers.parserconfigurationexception;  

import org.w3c.dom.document;  

public class adduserinterceptor extends abstractphaseinterceptor<soapmessage>{  

    private string username ;  

    private string password ;  

    public adduserinterceptor(string username, string password) {  

        this.username = username ;  

        this.password = password ;  

        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)) ;  

WebServices中使用cxf開發日志攔截器以及自定義攔截器

import com.wiseweb.client.interceptor.adduserinterceptor;  

public class clienttest2 {  

        outinterceptors.add(new adduserinterceptor("benjamin", "123456")) ;  

運作結果server和client比較:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

使用者名與密碼正确,通過驗證!  

WebServices中使用cxf開發日志攔截器以及自定義攔截器

如果輸入的使用者名和密碼不正确,運作結果為:

WebServices中使用cxf開發日志攔截器以及自定義攔截器

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  

WebServices中使用cxf開發日志攔截器以及自定義攔截器

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.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.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.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  

這樣就可以有效的驗證訪客的身份。