HttpServletRequestWrapper原理加静态代理

本文介绍如何利用装饰模式增强Filter的功能,通过对HttpServletRequest进行包装,实现请求参数的预处理,包括去除空白字符及解决中文乱码问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HttpServletRequestWrapper

 

Filter能在request到达servlet的服务方法之前拦截HttpServletRequest对象,而在服务方 法转移控制后又能拦截HttpServletResponse对象。

你可以使用filter来实现特定的任务,比如验证用户输入,以及压缩web内容。但HttpServletRequest对象的参数是不可改变的,这极大地缩减了filter的应用范围。至少在一半的时间里,你希望可以改变准备传送给 filter的对象。
幸运的是,尽管你不能改变不变对象本身,但你却可以通过使用装饰模式来改变其状态。 

 

Example1:
一个删除空白字符的Filter 

 

HttpServerletRequest装饰类

 

[java]  view plain  copy
  1. import javax.servlet.http.HttpServletRequest;  
  2. import javax.servlet.http.HttpServletRequestWrapper;  
  3.   
  4. public final class MyRequestWrapper extends HttpServletRequestWrapper {  
  5.     public MyRequestWrapper(HttpServletRequest servletRequest) {  
  6.         super(servletRequest);  
  7.     }  
  8.   
  9.     public String[] getParameterValues(String parameter) {  
  10.         String[] results = super.getParameterValues(parameter);  
  11.         if (results == null) {  
  12.             return null;  
  13.         }  
  14.         int count = results.length;  
  15.         String[] trimResults = new String[count];  
  16.   
  17.         for (int i = 0; i < count; i++) {  
  18.             trimResults[i] = results[i].trim();  
  19.         }  
  20.         return trimResults;  
  21.     }  
  22. }  

 

如何载获Http请求并装饰HttpServletRequest对象

[java]  view plain  copy
  1. public class MyFilter implements Filter {  
  2.     private FilterConfig filterConfig;  
  3.   
  4.     public void init(FilterConfig filterConfig) throws ServletException {  
  5.         System.out.println("Filter initialized");  
  6.         this.filterConfig = filterConfig;  
  7.     }  
  8.   
  9.     public void destroy() {  
  10.         System.out.println("Filter destroyed");  
  11.         this.filterConfig = null;  
  12.     }  
  13.   
  14.     public void doFilter(ServletRequest request, ServletResponse response,  
  15.         FilterChain chain) throws IOException, ServletException {  
  16.         chain.doFilter(new MyRequestWrapper((HttpServletRequest) request),  
  17.             response);  
  18.     }  
  19. }  

 

 

Example2:

通过HttpServletRequestWrapper(装饰模式的应用)来解决中文乱码问题

自定义请求包装器包装请求,将字符编码转换的工作添加到getParameter()方法中

[java]  view plain  copy
  1. mport java.io.UnsupportedEncodingException;    
  2. import java.net.URLDecoder;    
  3.     
  4. import javax.servlet.http.HttpServletRequest;    
  5. import javax.servlet.http.HttpServletRequestWrapper;    
  6.     
  7. public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {    
  8.     
  9.     private String charset = "UTF-8";    
  10.     
  11.     public GetHttpServletRequestWrapper(HttpServletRequest request) {    
  12.         super(request);    
  13.     }    
  14.     
  15.     /**  
  16.      * 获得被装饰对象的引用和采用的字符编码  
  17.      * @param request  
  18.      * @param charset  
  19.      */    
  20.     public GetHttpServletRequestWrapper(HttpServletRequest request,    
  21.             String charset) {    
  22.         super(request);    
  23.         this.charset = charset;    
  24.     }    
  25.     
  26.     /**  
  27.      * 实际上就是调用被包装的请求对象的getParameter方法获得参数,然后再进行编码转换  
  28.      */    
  29.     public String getParameter(String name) {    
  30.         String value = super.getParameter(name);    
  31.         value = value == null ? null : convert(value);    
  32.         return value;    
  33.     }    
  34.     
  35.     public String convert(String target) {    
  36.         System.out.println("编码转换之前:" + target);    
  37.         try {    
  38.             return new String(target.trim().getBytes("ISO-8859-1"), charset);    
  39.         } catch (UnsupportedEncodingException e) {    
  40.             return target;    
  41.         }    
  42.     }    
  43.     
  44. }   

 

[java]  view plain  copy
  1. public void doFilter(ServletRequest request, ServletResponse response,    
  2.             FilterChain chain) throws IOException, ServletException {    
  3.         //设置请求响应字符编码    
  4.         request.setCharacterEncoding(charset);    
  5.         response.setCharacterEncoding(charset);    
  6.         //新增加的代码            
  7.         HttpServletRequest req = (HttpServletRequest)request;    
  8.             
  9.         if(req.getMethod().equalsIgnoreCase("get"))    
  10.         {    
  11.             req = new GetHttpServletRequestWrapper(req,charset);    
  12.         }    
  13.             
  14.         System.out.println("----请求被"+config.getFilterName()+"过滤");    
  15.         //传递给目标servlet或jsp的实际上时包装器对象的引用,而不是原始的HttpServletRequest对象    
  16.         chain.doFilter(req, response);    
  17.             
  18.         System.out.println("----响应被"+config.getFilterName()+"过滤");    
  19.     
  20.     }    

 这样一来,在servlet中调用包装器的getParameters方法来获取参数,就已经完成了字符编码的转换过程,我们就不需要在每次获取参数时来进行字符编码转换了。

例子来源:http://www.iteye.com/topic/483158

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值