一、前言
上一篇已經完整的描述了spring boot 與cxf整合工程,包括服務端的釋出以及客戶端的訪問。但是整個日誌輸出只有一個簡單的一句:
o.a.c.w.s.f.ReflectionServiceFactoryBean : Creating Service {http://ws.cxf.ouyushan.org/}UserServiceService from class org.ouyushan.cxf.ws.UserService
表示透過CXF已建立指定服務。但是webservice服務中設計的請求資訊一星半點都沒有,當服務出現問題時,如何透過獲取日誌來分析問題呢?
其實在CXF整合完成後,其它附加的高階功能基本上都是透過攔截器來實現的。日誌捕獲和輸出也是基於此實現的。
本文將帶領大家快速實現CXF日誌輸出功能。
專案原始碼: https://github.com/ouyushan/spring-webservice-samples
spring-cxf參考原始碼: https://github.com/code-not-found/cxf-jaxws
spring-ws參考原始碼: https://github.com/code-not-found/spring-ws
二、開發環境IDE::IDEA
JDK:1.8
maven:3.6.2
spring boot:2.4.0
cxf:3.4.1
三、實現步驟具體程式碼實現步驟和上篇一樣。本章在之前基礎上講解新增內容。
3.1、實現服務端和客戶端新建服務端和客戶端spring-cxf-client-logging、spring-cxf-server-logging,並完成服務部署和客戶端訪問介面,具體步驟見上一篇。
3.2、新增日誌輸出依賴spring boot與cxf整合後輸出業務日誌只需引入cxf-rt-features-logging,並實現日誌攔截器即可。
服務端、客服端pom檔案中新增cxf日誌依賴包
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-features-logging</artifactId> <version>3.4.1</version></dependency>
3.3、實現日誌輸出攔截器
在服務端和客戶端配置類中,新增請求接入和響應輸出日誌攔截器
@Beanpublic LoggingInInterceptor loggingInInterceptor() { return new LoggingInInterceptor();}@Beanpublic LoggingOutInterceptor loggingOutInterceptor() { return new LoggingOutInterceptor();}
服務端在Endpoint中配置新增的攔截器
// log the request and response messagesendpoint.getInInterceptors() .add(loggingInInterceptor());endpoint.getOutInterceptors() .add(loggingOutInterceptor());
客戶端在UserService中配置新增的攔截器
// log the request and response messagesjaxWsProxyFactoryBean.getInInterceptors() .add(loggingInInterceptor());jaxWsProxyFactoryBean.getOutInterceptors() .add(loggingOutInterceptor());
3.4、功能驗證
分別啟動服務端和客戶端,訪問客戶端請求介面:
http://localhost:7070/user/get?userId=1
客戶端控制檯輸出如下:
2020-11-26 20:22:00.884 INFO 8768 --- [nio-7070-exec-1] o.a.cxf.services.UserService.REQ_OUT : REQ_OUT Address: http://localhost:8080/ws/user HttpMethod: POST Content-Type: text/xml ExchangeId: 3140c6ed-a420-4dee-b970-4f9452b17d17 ServiceName: UserServiceService PortName: UserServicePort PortTypeName: UserService Headers: {SOAPAction="", Accept=*/*} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getUserName xmlns:ns2="http://ws.cxf.ouyushan.org/"><userId>1</userId></ns2:getUserName></soap:Body></soap:Envelope>2020-11-26 20:22:01.272 INFO 8768 --- [nio-7070-exec-1] o.a.cxf.services.UserService.RESP_IN : RESP_IN Address: http://localhost:8080/ws/user Content-Type: text/xml;charset=UTF-8 ResponseCode: 200 ExchangeId: 3140c6ed-a420-4dee-b970-4f9452b17d17 ServiceName: UserServiceService PortName: UserServicePort PortTypeName: UserService Headers: {Keep-Alive=timeout=60, connection=keep-alive, content-type=text/xml;charset=UTF-8, Content-Length=220, Date=Thu, 26 Nov 2020 12:22:01 GMT} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getUserNameResponse xmlns:ns2="http://ws.cxf.ouyushan.org/"><return>tom</return></ns2:getUserNameResponse></soap:Body></soap:Envelope>
服務端控制檯輸出如下:
2020-11-26 20:22:01.057 INFO 10604 --- [nio-8080-exec-4] o.a.cxf.services.UserService.REQ_IN : REQ_IN Address: http://localhost:8080/ws/user HttpMethod: POST Content-Type: text/xml; charset=UTF-8 ExchangeId: 3a1a8ecf-f857-4472-9f56-165b54144dae ServiceName: UserService PortName: UserServiceImplPort PortTypeName: UserService Headers: {SOAPAction="", Accept=*/*, host=localhost:8080, connection=keep-alive, content-type=text/xml; charset=UTF-8, cache-control=no-cache, Content-Length=202, pragma=no-cache, user-agent=Apache-CXF/3.4.1} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getUserName xmlns:ns2="http://ws.cxf.ouyushan.org/"><userId>1</userId></ns2:getUserName></soap:Body></soap:Envelope>2020-11-26 20:22:01.108 INFO 10604 --- [nio-8080-exec-4] o.a.cxf.services.UserService.RESP_OUT : RESP_OUT Address: http://localhost:8080/ws/user Content-Type: text/xml ResponseCode: 200 ExchangeId: 3a1a8ecf-f857-4472-9f56-165b54144dae ServiceName: UserService PortName: UserServiceImplPort PortTypeName: UserService Headers: {} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getUserNameResponse xmlns:ns2="http://ws.cxf.ouyushan.org/"><return>tom</return></ns2:getUserNameResponse></soap:Body></soap:Envelope>
從日誌可以看出完整的請求鏈路資訊
四、總結透過本篇教材,您應該已掌握Spring Boot整合CXF實現服務端、客戶端日誌的配置與輸出。整個過程可分為兩步:
定義日誌輸入、輸出攔截器;在服務端EndPoint中設定日誌攔截器/在客戶端代理工廠JaxWsProxyFactoryBean中設定日誌攔截器。獲取服務日誌的問題已解決了,服務就這樣能上線嗎?尤其是在保險、銀行等公司對接時。結果肯定是否定的,針對敏感資訊的服務會話,至少得對會話內容進行加解密甚至簽名和驗籤吧。
具體怎麼實現會話的加解密、簽名及驗籤將在下一篇教材中進行講解。