1. 程式人生 > >通過反射讀取HttpServletResponse輸出至客戶端的流

通過反射讀取HttpServletResponse輸出至客戶端的流

這幾天在學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