高手不得不会的东西--HttpServletRequestWrapper、HttpServletResponseWrapper,HttpSessionWrapper用法

高手不得不会的东西

背景:项目使用的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用法 
[java]  view plain copy
  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.     }  

[java]  view plain copy
  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. }  

调用处 
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  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
首先说一个无关的,但高手必须了解的。 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 CacheHettpServletRespons eWrapper(HttpServletResponse response){
.......
}
//重写HettpServletResponseWrap per的一个方法,这里可能不是write方法,忘记叫什么了,自己去看。后来看了下是
  1. /覆盖getWriter()方法,使用我们自己定义的Writer     
  2.     public PrintWriter getWriter() throws IOException  

HettpServletResponseWrap per吧
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

--------------------------------------------------
页面缓存
---》html--->client
二级缓存
--》action-->service层--> Jsp-->html-->client

:从上看出为什么页面缓存要比二级缓存要快。因为二级缓存处理流程更多,并且还要解析jsp及标签等转化成html,这是耗时的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值