通過反射讀取HttpServletResponse輸出至客戶端的流
阿新 • • 發佈:2019-01-05
這幾天在學Spring MVC,於是也學了點Spring攔截器。本來想通過攔截器擷取response物件中使用者登入成功與否的狀態。但發現response物件只做輸出,所以得不到裡面的值。於是就各種百度、GOOGLE。發現大多的方法都是放在Controller被呼叫之前,那樣的確不錯,但那樣不符合我現在的情況。我需要的是僅僅在Controller呼叫之後。
然後自己除錯了~~~發現應該很好取的。。沒有網上講的那麼麻煩
直接看怎麼做吧。。
CoyoteOutputStream os = (CoyoteOutputStream) response.getOutputStream();
先給出一個完整的程式碼
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.connector.CoyoteOutputStream; import org.apache.catalina.connector.OutputBuffer; import org.apache.tomcat.util.buf.ByteChunk; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public class SecurityInterceptor implements HandlerInterceptor { /** * 方法執行成功之後回撥的方法 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object obj, Exception exception) throws Exception { // 擷取響應流 CoyoteOutputStream os = (CoyoteOutputStream) response.getOutputStream(); // 取到流物件對應的Class物件 Class<CoyoteOutputStream> c = CoyoteOutputStream.class; // 取出流物件中的OutputBuffer物件,該物件記錄響應到客戶端的內容 Field fs = c.getDeclaredField("ob"); if (fs.getType().toString().endsWith("OutputBuffer")) { fs.setAccessible(true);// 設定訪問ob屬性的許可權 OutputBuffer ob = (OutputBuffer) fs.get(os);// 取出ob Class<OutputBuffer> cc = OutputBuffer.class; Field ff = cc.getDeclaredField("outputChunk");// 取到OutputBuffer中的輸出流 ff.setAccessible(true); if (ff.getType().toString().endsWith("ByteChunk")) { ByteChunk bc = (ByteChunk) ff.get(ob);// 取到byte流 String val = new String(bc.getBytes(), "UTF-8");// 最終的值 System.out.println(val); } } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object obj, ModelAndView mav) throws Exception { } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception { return true; } }
附:
要用到Tomcat中的包,我在Tomcat6.x中的libs目錄找的。
tomcat-coyote.jar
catalina.jar