差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

java:web:resteasy:fetch_raw_message [2018/07/01 20:16]
tony [ReadInterceptor & InputStreamSniffer]
java:web:resteasy:fetch_raw_message [2023/06/25 09:48]
行 1: 行 1:
-{{tag>​resteasy}} 
-====== How to fetch raw message after the request is failed? (working) ====== 
-===== Problem ===== 
-RESTEasy jackson provider讓我們可以輕鬆的將第三方服務回應的json內容,轉成我們自己的物件,讓程式碼只專注於資源物件的操作;然而,第三方服務並非永遠都如你預期,它可能突然更新甚至吐出你不認得的訊息:​ 
-<​code>​ 
-javax.ws.rs.ProcessingException:​ RESTEASY003145:​ Unable to find a MessageBodyReader of content-type text/​html;​charset=iso-8859-1 
-</​code>​ 
-我有幸遇到這樣的問題,也讓我思考著該如何將原始資料記錄下來以回報第三方服務提供者。本篇文章分享可能的作法,可依照你的需求自行挑選。 
-===== How to resolve? ===== 
-==== ReadInterceptor & InputStreamSniffer ==== 
-一開始遇到這個問題時,我的想法是:​ 是否可以透過[[https://​blog.wfyvv.com/​blog/​2018/​03/​jax-rs/​|interceptor]]去處理?​ 我所提供的第一個方法,是註冊一個ReadInterceptor,並且wrap原始的InputStream,將讀取的內容給記錄下來。首先是ReaderInterceptor,它會從Context中取出InputStream,並將其wrap成InputStreamSniffer,代整個讀取流程執行後,可以透過getReadContent去拿到讀取的內容:​ 
-<code java> 
-@Provider 
-public class SnifferReadInterceptor implements ReaderInterceptor { 
- 
- private InputStreamSniffer inputStreamSniffer = null; 
-  
- @Override 
- public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException,​ WebApplicationException { 
- InputStream inputStream = context.getInputStream();​ 
-  
- inputStreamSniffer = new InputStreamSniffer(inputStream);​ 
- context.setInputStream(inputStreamSniffer);​ 
-  
- return context.proceed();​ 
- } 
- 
- public String getReadContent(){ 
- return inputStreamSniffer.getContent();​ 
- } 
-} 
-</​code>​ 
-InputStreamSniffer則是將讀取的動作delegate給原始的InputStream,並悄悄地記下讀取內容:​ 
-<code java> 
-public class InputStreamSniffer extends InputStream { 
- 
- private InputStream srcInputStream;​ 
- private StringBuilder contentStringBuilder;​ 
-  
- public InputStreamSniffer(InputStream inputStream){ 
- srcInputStream = inputStream;​ 
- contentStringBuilder = new StringBuilder();​ 
- } 
-  
- @Override 
- public int read() throws IOException { 
- int read_c = srcInputStream.read();​ 
- contentStringBuilder.append((char)read_c);​ 
- return read_c; 
- } 
- // .. skip 
-</​code>​ 
- 
- 
-===== Reference ===== 
-  - [[https://​blog.wfyvv.com/​blog/​2018/​03/​jax-rs/​|JAX-RS 2.0 简介及其过滤器与拦截器]] 
-