攔截器(Interceptor)是CXF功能最主要的擴展點,可以在不對核心模塊進行修改的情況下,動態添加很多功能。攔截器和JAX-WS Handler、Filter的功能類似,當服務被調用時,就會創建一個攔截器鏈(Interceptor Chain),攔截器鏈在服務輸入(IN)或輸出(OUT)階段實現附加功能。
攔截器可以在客戶端,也可以在服務端添加。當客戶端發起一個WebService請求時,在客戶端會創建輸出攔截器鏈,服務端接收到客戶端的後,會創建輸入攔截器鏈。當服務端返回響應消息時,響應消息會經過服務端的輸出攔截鏈,客戶端接收到服務端的響應時,會創建輸入攔截器鏈,響應消息先經過輸入攔截器鏈處理。攔截器在服務端和客戶端的作用如圖所示。
攔截器鏈階段
攔截器鏈有多個階段,每個階段都有多個攔截器。攔截器在攔截器鏈的哪個階段起作用,可以在攔截器的構造函數中聲明。
輸入攔截器鏈有如下幾個階段,這些階段按照在攔截器鏈中的先後順序排列。
階段名稱 | 階段功能描述 |
---|---|
RECEIVE | Transport level processing(接收階段,傳輸層處理) |
(PRE/USER/POST)_STREAM | Stream level processing/transformations(流處理/轉換階段) |
READ | This is where header reading typically occurs(SOAPHeader讀取) |
(PRE/USER/POST)_PROTOCOL | Protocol processing, such as JAX-WS SOAP handlers(協議處理階段,例如JAX-WS的Handler處理) |
UNMARSHAL | Unmarshalling of the request(SOAP請求解碼階段) |
(PRE/USER/POST)_LOGICAL | Processing of the umarshalled request(SOAP請求解碼處理階段) |
PRE_INVOKE | Pre invocation actions(調用業務處理之前進入該階段) |
INVOKE | Invocation of the service(調用業務階段) |
POST_INVOKE | Invocation of the outgoing chain if there is one(提交業務處理結果,並觸發輸入連接器) |
輸出攔截器鏈有如下幾個階段,這些階段按照在攔截器鏈中的先後順序排列。
階段名稱 | 階段功能描述 |
---|---|
SETUP | Any set up for the following phases(設置階段) |
(PRE/USER/POST)_LOGICAL | Processing of objects about to marshalled |
PREPARE_SEND | Opening of the connection(消息發送準備階段,在該階段創建Connection) |
PRE_STREAM | 流準備階段 |
PRE_PROTOCOL | Misc protocol actions(協議準備階段) |
WRITE | Writing of the protocol message, such as the SOAP Envelope.(寫消息階段) |
MARSHAL | Marshalling of the objects |
(USER/POST)_PROTOCOL | Processing of the protocol message |
(USER/POST)_STREAM | Processing of the byte level message(字節處理階段,在該階段把消息轉爲字節) |
SEND | 消息發送 |
在輸出攔截器鏈的SEND階段後,還會觸發以_ENDING結尾階段,這些ENDING階段與以上階段對應,主要用於清理或者關閉資源。ENDING階段觸發的順序如下:
- SEND_ENDING
- POST_STREAM_ENDING
- USER_STREAM_ENDING
- POST_PROTOCOL_ENDING
- USER_PROTOCOL_ENDING
- MARSHAL_ENDING
- WRITE_ENDING
- PRE_PROTOCOL_ENDING
- PRE_STREAM_ENDING
- PREPARE_SEND_ENDING
- POST_LOGICAL_ENDING
- USER_LOGICAL_ENDING
- PRE_LOGICAL_ENDING
- SETUP_ENDING
CXF默認攔截器鏈
在CXF中,所有對消息的處理都是通過各種攔截器實現。CXF已經實現了多種攔截器,如操縱消息頭、執行認證檢查、驗證消息數據、日誌記錄、消息壓縮等,有些攔截器在發佈服務、訪問服務時已經默認添加到攔截器鏈。
CXF默認輸入攔截器鏈,如果沒有添加額外的攔截器,CXF輸入會順序經過以下攔截器:
攔截器名稱 | 攔截器功能 |
---|---|
AttachmentInInterceptor | Parse the mime headers for mime boundaries, finds the “root” part and resets the input stream to it, and stores the other parts in a collection of Attachments |
StaxInInterceptor | Creates an XMLStreamReader from the transport InputStream on the Message |
ReadHeadersInterceptor | Parses the SOAP headers and stores them on the Message |
SoapActionInInterceptor | Parses “soapaction” header and looks up the operation if a unique operation can be found for that action. |
MustUnderstandInterceptor | Checks the MustUnderstand headers, its applicability and process it, if required |
SOAPHandlerInterceptor | SOAP Handler as per JAX-WS |
LogicalHandlerInInterceptor | Logical Handler as per JAX-WS |
CheckFaultInterceptor | Checks for fault, if present aborts interceptor chain and invokes fault handler chain |
URIMappingInterceptor | Can handle HTTP GET, extracts operation info and sets the same in the Message |
DocLiteralnInterceptor | Examines the first element in the SOAP body to determine the appropriate Operation (if soapAction did not find one) and calls the Databinding to read in the data. |
SoapHeaderInterceptor | Perform databinding of the SOAP headers for headers that are mapped to parameters |
WrapperClassInInterceptor | For wrapped doc/lit, the DocLiteralInInterceptor probably read in a single JAXB bean. This interceptor pulls the individual parts out of that bean to construct the Object[] needed to invoke the service. |
SwAInInterceptor | For Soap w/ Attachments, finds the appropriate attachments and assigns them to the correct spot in the parameter list. |
HolderInInterceptor | For OUT and IN/OUT parameters, JAX-WS needs to create Holder objects. This interceptor creates the Holders and puts them in the parameter list. |
ServiceInvokerInInterceptor | Actually invokes the service. |
CXF默認輸出攔截器鏈,如果沒有添加額外的攔截器,CXF輸入會順序經過以下攔截器:
攔截器名稱 | 攔截器功能 |
---|---|
HolderOutInterceptor | For OUT and IN/OUT params, pulls the values out of the JAX-WS Holder objects (created in HolderInInterceptor) and adds them to the param list for the out message. |
SwAOutInterceptor | For OUT parts that are Soap attachments, pulls them from the list and holds them for later. |
WrapperClassOutInterceptor | For doc/lit wrapped, takes the remaining parts and creates a wrapper JAXB bean to represent the whole message. |
SoapHeaderOutFilterInterceptor | Removes inbound marked headers |
SoapActionOutInterceptor | Sets the SOAP Action |
MessageSenderInterceptor | Calls back to the Destination object to have it setup the output streams, headers, etc… to prepare the outgoing transport. |
SoapPreProtocolOutInterceptor | This interceptor is responsible for setting up the SOAP version and header, so that this is available to any pre-protocol interceptors that require these to be available. |
AttachmentOutInterceptor | If this service uses attachments (either SwA or if MTOM is enabled), it sets up the Attachment marshallers and the mime stuff that is needed. |
StaxOutInterceptor | Creates an XMLStreamWriter from the OutputStream on the Message. |
SoapHandlerInterceptor | JAX-WS SOAPHandler |
SoapOutInterceptor | Writes start element for soap:envelope and complete elements for other header blocks in the message. Adds start element for soap:body too. |
LogicalHandlerOutInterceptor | JAX-WS Logical handler stuff |
WrapperOutInterceptor | If wrapped doc/lit and not using a wrapper bean or if RPC lit, outputs the wrapper element to the stream. |
BareOutInterceptor | Uses the databinding to write the params out. |
SoapOutInterceptor$SoapOutEndingInterceptor | Closes the soap:body and soap:envelope |
StaxOutInterceptor$StaxOutEndingInterceptor | Flushes the stax stream. |
MessageSenderInt$MessageSenderEnding | Closes the exchange, lets the transport know everything is done and should be flushed to the client. |