HttpServletRequestWrapper、HttpServletResponseWrapper,HttpSessionWrapper用法
轉載自:http://blog.csdn.net/it_man/article/details/7556903背景:項目使用的SOA架構,使用Oracle10G SOA SUITE,在該套件中增加了一個過濾器用於解析設置的訪問策略。在其中遇到了一個問題,Oracle10g無法將IP與實例編號進行綁定,於是乎從過濾器入手,嘗試了HttpServletRequestWrapper、HttpServletResponseWrapper攔截設置參數的方法。得到的結果request可以對請求參數進行修改,但是這樣可能會導致Oracle10g SOA Suite的正常運行,想從response中獲得返回的內容,但是得到的結果是null,到目前為止該問題仍舊沒有得到解決,有好辦法的歡迎聯系本人,謝謝。
1)建立一個響應包裝器。擴展javax.servlet.http.HttpServletResponseWrapper。 2)提供一個緩存輸出的PrintWriter。重載getWriter方法,返回一個保存發送給它的所有東西的PrintWriter,並把結果存進一個可以稍後訪問的字段中。 3)傳遞該包裝器給doFilter。此調用是合法的,因為HttpServletResponseWrapper實現HttpServletResponse。 4)提取和修改輸出。在調用FilterChain的doFilter方法後,原資源的輸出只要利用步驟2中提供的機制就可以得到。只要對你的應用適合,就可以修改或替換它。 5)發送修改過的輸出到客戶機。因為原資源不再發送輸出到客戶機(這些輸出已經存放到你的響應包裝器中了),所以必須發送這些輸出。這樣,你的過濾器需要從原響應對象中獲得PrintWriter或OutputStream,並傳遞修改過的輸出到該流中。 (2).GZipFilter類 (3).GZipUtil類 (4).在web.xml中配置 GZipFilter |
下附HttpServletRequestWrapper、HttpServletResponseWrapper用法
1 class FilteredRequest extends HttpServletRequestWrapper 2 { 3 4 public FilteredRequest(ServletRequest request) 5 { 6 super((HttpServletRequest) request);7 } 8 9 public String getParameter(String paramName) 10 { 11 String value = super.getParameter(paramName); 12 if ("myParameter".equals(paramName)) 13 { 14 // 更改請求參數的值 15 value += "|127.0.0.1"; 16 } 17 return value; 18 } 19 20 public String[] getParameterValues(String paramName) 21 { 22 String values[] = super.getParameterValues(paramName); 23 return values; 24 } 25 }
1 import java.io.ByteArrayOutputStream; 2 import java.io.IOException; 3 import java.io.PrintWriter; 4 import java.io.UnsupportedEncodingException; 5 6 import javax.servlet.ServletResponse; 7 import javax.servlet.http.HttpServletResponse; 8 import javax.servlet.http.HttpServletResponseWrapper; 9 10 public class WrapperResponse extends HttpServletResponseWrapper 11 { 12 private MyPrintWriter tmpWriter; 13 14 private ByteArrayOutputStream output; 15 16 public WrapperResponse(ServletResponse httpServletResponse) 17 { 18 super((HttpServletResponse)httpServletResponse); 19 output = new ByteArrayOutputStream(); 20 tmpWriter = new MyPrintWriter(output); 21 } 22 23 public void finalize() throws Throwable 24 { 25 super.finalize(); 26 output.close(); 27 tmpWriter.close(); 28 } 29 30 public String getContent() 31 { 32 try 33 { 34 tmpWriter.flush(); //刷新該流的緩沖,詳看java.io.Writer.flush() 35 String s = tmpWriter.getByteArrayOutputStream().toString("UTF-8"); 36 //此處可根據需要進行對輸出流以及Writer的重置操作 37 //比如tmpWriter.getByteArrayOutputStream().reset() 38 return s; 39 } catch (UnsupportedEncodingException e) 40 { 41 return "UnsupportedEncoding"; 42 } 43 } 44 45 //覆蓋getWriter()方法,使用我們自己定義的Writer 46 public PrintWriter getWriter() throws IOException 47 { 48 return tmpWriter; 49 } 50 51 public void close() throws IOException 52 { 53 tmpWriter.close(); 54 } 55 56 //自定義PrintWriter,為的是把response流寫到自己指定的輸入流當中 57 //而非默認的ServletOutputStream 58 private static class MyPrintWriter extends PrintWriter 59 { 60 ByteArrayOutputStream myOutput; //此即為存放response輸入流的對象 61 62 public MyPrintWriter(ByteArrayOutputStream output) 63 { 64 super(output); 65 myOutput = output; 66 } 67 68 public ByteArrayOutputStream getByteArrayOutputStream() 69 { 70 return myOutput; 71 } 72 } 73 }
調用處
1 FilteredRequest filterRequest = new FilteredRequest(request); 2 WrapperResponse filterResponse = new WrapperResponse(response); 3 filterChain.doFilter(filterRequest, filterResponse); 4 String content = filterResponse.getContent();或者自己實現HttpServletResponse和HttpServletRequest接口,但這是麻煩的。 如果要管理session,或session實現共享就用HttpSessionWrapper
學習oscache頁面緩存得到的啟示
:http://blog.sina.com.cn/s/blog_866b16a60100z2bi.html 首先說一個無關的,但高手必須了解的。 servlet的Response的輸出流在URL中保存Session ID的方法是哪一個? A. the encodeURL method of the HttpServletRequest interface B. the encodeURL method of the HttpServletResponse interface C. the rewriteURL method of the HttpServletRequest interface D. the rewriteURL method of the HttpServletResponse interface 答案選B. 學習完黎老師講的oscache頁面緩存後,它的實現原理大致如下(原理和oscache一樣,但oscache做的更好,我這裏只是用偽代碼簡單描述): Cachefilter implements filter{ dofilter(request, response, chain){ String urlpath = req,...; if(Oscache.contains(urlpath)){ String content = oscache.getKey(urlpath); response.write(content); }else{ CacheHettpServletResponseWrapper wrapper = new CacheHettpServletResponseWrapper (respone); chain.doFilter(reques, wrapper); String content = wrapper.getContent();//獲取服務端往客戶端輸出的html代碼 Oscache.put(urlpath, content); response.write(content); } } }public CacheHettpServletResponseWrapper extends HettpServletResponseWrapper{ private String content; public CacheHettpServletResponseWrapper(HttpServletResponse response){ ....... } //重寫HettpServletResponseWrapper的一個方法,這裏可能不是write方法,忘記叫什麽了,自己去看。後來看了下是
1 //覆蓋getWriter()方法,使用我們自己定義的Writer 2 public PrintWriter getWriter() throws IOException
HettpServletResponseWrapper吧
public void getWriter(String Content){ this.Content = content; } public String getContent(){ return this.content; } } :利用繼承HettpServletResponseWrapper可以控制往客戶端的輸出,或在往客戶端輸出前取得要輸出的內容。 同樣希望大家會HttpServletRequestWrapper。 或者自己實現HttpServletResponse和HttpServletRequest接口,但這是麻煩的。
1)建立一個響應包裝器。擴展javax.servlet.http.HttpServletResponseWrapper。 2)提供一個緩存輸出的PrintWriter。重載getWriter方法,返回一個保存發送給它的所有東西的PrintWriter,並把結果存進一個可以稍後訪問的字段中。 3)傳遞該包裝器給doFilter。此調用是合法的,因為HttpServletResponseWrapper實現HttpServletResponse。 4)提取和修改輸出。在調用FilterChain的doFilter方法後,原資源的輸出只要利用步驟2中提供的機制就可以得到。只要對你的應用適合,就可以修改或替換它。 5)發送修改過的輸出到客戶機。因為原資源不再發送輸出到客戶機(這些輸出已經存放到你的響應包裝器中了),所以必須發送這些輸出。這樣,你的過濾器需要從原響應對象中獲得PrintWriter或OutputStream,並傳遞修改過的輸出到該流中。 (2).GZipFilter類 (3).GZipUtil類 (4).在web.xml中配置 GZipFilter |
HttpServletRequestWrapper、HttpServletResponseWrapper,HttpSessionWrapper用法