全国咨询/投诉热线:400-618-4000

WEB前端培训之HttpServletRequestWrapper 用法

更新时间:2016年11月29日15时34分 来源:传智播客web前端培训学院 浏览次数:

WEB前端培训之HttpServletRequestWrapper 用法


Servlet规范中所引入的filter令人心动不已,因为它引入了一个功能强大的拦截模式。Filter是这样一种Java对象,它能在request到达servlet的服务方法之前拦截HttpServletRequest对象,而在服务方法转移控制后又能拦截HttpServletResponse对象。你可以使用filter来实现特定的任务,比如验证用户输入,以及压缩web内容。但你拟富有成效地使用过滤器的念头却被你不能改变HttpServletRequest对象的参数的现实扫了兴,因为java.util.Map所包装的HttpServletRequest对象的参数是不可改变的。这极大地缩减了filter的应用范围。至少在一半的时间里,你希望可以改变准备传送给filter的对象。如果在HttpServletRequest对象到达Struts的action  servlet之前,我们可以通过一个filter将用户输入的多余空格去掉,难道不是更美妙吗?这样的话,你就不必等到在Struts的action表单验证方法中才进行这项工作了。 
幸运的是,尽管你不能改变不变对象本身,但你却可以通过使用装饰模式来改变其状态。 
现在,让我们来看看,如何编写自己的HttpServletRequest装饰类。 

一个删除空白字符的Filter 
本节将以上的理论投入实际使用,通过实现一个删除空白字符的filter,来演示如何使用javax.servlet.http.HttpServletRequestWrapper类来装饰HttpServletRequest对象。在本例中,这个filter将删除所传来的参数中多余的空白字符。 
这在许多servlet/JSP应用中是很有用的,包括Struts及JavaServer  Faces等应用。例如,Struts通过调用HttpServletRequest对象的getParameterValues()对象来处理action表单。通过覆盖装饰类中此方法,你可以改变当前HttpServletRequest对象的状态。 
要创建HttpServletRequest的装饰类,你需要继承HttpServletRequestWrapper并且覆盖你希望改变的方法。列表5中,MyRequestWrapper类将删除getParameterValues()方法返回值的多余空白字符。 

列表5:HttpServerletRequest装饰类 
程序代码: 
package trimmer.filter; 

import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletRequestWrapper; 

public final class MyRequestWrapper extends HttpServletRequestWrapper { 
public MyRequestWrapper(HttpServletRequest servletRequest) { 
super(servletRequest); 


public String[] getParameterValues(String parameter) { 
String[] results = super.getParameterValues(parameter); 
if (results == null) 
return null; 
int count = results.length; 
String[] trimResults = new String[count]; 
for (int i = 0; i < count; i++) { 
trimResults[i] = results[i].trim(); 

return trimResults; 


列表6演示了如何载获Http请求并装饰HttpServletRequest对象。[i]列表6:删除空白符的filter 


列表6演示了如何载获Http请求并装饰HttpServletRequest对象。 

[i]列表6:删除空白符的filter 
程序代码: 
package trimmer.filter; 

import java.io.IOException; 
import javax.servlet.Filter; 
import javax.servlet.FilterChain; 
import javax.servlet.FilterConfig; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRequest; 
import javax.servlet.ServletResponse; 
import javax.servlet.http.HttpServletRequest; 

public class MyFilter implements Filter { 
private FilterConfig filterConfig; 

public void init(FilterConfig filterConfig) throws ServletException { 
System.out.println("Filter initialized"); 
this.filterConfig = filterConfig; 


public void destroy() { 
System.out.println("Filter destroyed"); 
this.filterConfig = null; 


public void doFilter(ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException { 
chain.doFilter(new MyRequestWrapper((HttpServletRequest) request), 
response); 


这个程序使用了列表6所示的filter来修整用户输入。要使用这个filter,你需要在web.xml文件中如下设置filter及filter-mapping的元素。 
   
<filter> 
       <filter-name>TrimmerFilter</filter-name> 
       <filter-class>trimmer.filter.MyFilter</filter-class> 
   </filter> 
   <filter-mapping> 
       <filter-name>TrimmerFilter</filter-name> 
       <url-pattern>*.do</url-pattern> 
   </filter-mapping> 


要测试这个filter,启动这个应用后,在表单中输入一些值,提交表单,看看这个filter是如何修整输入数值的。这是一个实用的装饰模式的应用。 

小结 
Servlet  filter可以在调用一个servlet的服务方法后,拦载或加工HTTP请求。尽管这非常诱人,但其实际使用却有所限制,因为你不能改变HttpServletRequest对象。 
这时候装饰模式派上了用场。本文演示了如何通过应用装饰模式来“修改”HttpServletRequest对象,从而使你的servlet  filter更加有用。在上面filter例子中,filter改了request参数中的用户输入,而这一点,如果没有装饰request对象,你是无论如何也不可能做到的。 




--------------------------------------------------------- 
package wrapper;   
  
import java.io.UnsupportedEncodingException;   
import java.net.URLDecoder;   
  
import javax.servlet.http.HttpServletRequest;   
import javax.servlet.http.HttpServletRequestWrapper;   
  
public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {   
  
    private String charset = "UTF-8";   
  
    public GetHttpServletRequestWrapper(HttpServletRequest request) {   
        super(request);   
    }   
  
    /**  
     * 获得被装饰对象的引用和采用的字符编码  
     * @param request  
     * @param charset  
     */  
    public GetHttpServletRequestWrapper(HttpServletRequest request,   
            String charset) {   
        super(request);   
        this.charset = charset;   
    }   
  
    /**  
     * 实际上就是调用被包装的请求对象的getParameter方法获得参数,然后再进行编码转换  
     */  
    public String getParameter(String name) {   
        String value = super.getParameter(name);   
        value = value == null ? null : convert(value);   
        return value;   
    }   
  
    public String convert(String target) {   
        System.out.println("编码转换之前:" + target);   
        try {   
            return new String(target.trim().getBytes("ISO-8859-1"), charset);   
        } catch (UnsupportedEncodingException e) {   
            return target;   
        }   
    }   
  

------------ 
public void doFilter(ServletRequest request, ServletResponse response,   
            FilterChain chain) throws IOException, ServletException {   
        //设置请求响应字符编码   
        request.setCharacterEncoding(charset);   
        response.setCharacterEncoding(charset);   
        //新增加的代码           
        HttpServletRequest req = (HttpServletRequest)request;   
           
        if(req.getMethod().equalsIgnoreCase("get"))   
        {   
            req = new GetHttpServletRequestWrapper(req,charset);   
        }   
           
        System.out.println("----请求被"+config.getFilterName()+"过滤");   
        //传递给目标servlet或jsp的实际上时包装器对象的引用,而不是原始的HttpServletRequest对象   
        chain.doFilter(req, response);   
           
        System.out.println("----响应被"+config.getFilterName()+"过滤");   
  
    } 
本文版权归传智播客web前端开发学院所有,欢迎转载,转载请注明作者出处,谢谢!
作者:传智播客web前端培训学院;
首发:http://www.itcast.cn/web/ 
8种

javaee

python

web

ui

cloud

test

c

netmarket

pm

Linux

movies

robot

uids

北京校区

    14天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    15天免费试学

    基础班入门课程限时免费

    申请试学名额

    20天免费试学

    基础班入门课程限时免费

    申请试学名额

    8天免费试学

    基础班入门课程限时免费

    申请试学名额

    20天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    0天免费试学

    基础班入门课程限时免费

    申请试学名额

    12天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    5天免费试学

    基础班入门课程限时免费

    申请试学名额

    10天免费试学

    基础班入门课程限时免费

    申请试学名额