2017-05-25 23 views

回答

2

HttpServletRequest是一个HTTP特定的servlet请求的接口。通常,您会在servlet filtersservlets中获得此接口的实例。

有时您想在某个时刻调整原始请求。使用HttpServletRequestWrapper,您可以包装原始请求并覆盖一些方法,以使其行为稍有不同。

实施例:

你有一堆servlet和JSP,其期望在一定的格式一些请求参数。例如。日期格式为yyyy-MM-dd

现在需要以不同的格式支持日期,如dd.MM.yyyy具有相同的功能。假设没有中央字符串日期函数(它是继承的遗留应用程序),您必须在servlet和JSP中查找所有位置。

作为替代方案,您可以实现一个servlet过滤器。您映射过滤器,以便对您的servlet和JSP的所有请求都将通过此过滤器。

该过滤器的目的是检查日期参数的格式,并根据需要将它们重新格式化为旧格式。 servlet和JSP会始终以预期的旧格式获取日期字段。无需改变它们。

这是你的过滤器的骨架:

public void doFilter(ServletRequest request, ServletResponse response, 
    FilterChain chain) throws IOException, ServletException { 
    HttpServletRequest adjustedRequest = adjustParamDates((HttpServletRequest) request); 
    chain.doFilter(adjustedRequest, response); 
} 

我们采取的原始请求和方法adjustParamDates()我们处理该请求,并将它传递下来的过滤器链。

现在,我们将如何实施adjustParamDates()

private HttpServletRequest adjustParamDates(HttpServletRequest req) { 
    // ??? 
} 

我们需要接口HttpServletRequest的新实例,它的行为完全一样的原始实例req。但是getParameter(),getParameterMap(),getParameterNames(),getParameterValues()这四种方法不应该在原始参数上工作,而是在调整后的参数集上工作。接口HttpServletRequest的所有其他方法应该像原始方法一样运行。

所以我们可以这样做。我们创建一个HttpServletRequest的实例并实现所有方法。通过调用原始请求实例的相应方法,大多数方法实现非常简单:

private HttpServletRequest adjustParamDates(final HttpServletRequest req) { 
    final Map<String, String[]> adjustedParams = reformatDates(req.getParameterMap()); 
    return new HttpServletRequest() { 
    public boolean authenticate(HttpServletResponse response) { 
     return req.authenticate(response); 
    } 

    public String changeSessionId() { 
     return req.changeSessionId(); 
    } 

    public String getContextPath() { 
     return req.getContextPath(); 
    } 

    // Implement >50 other wrapper methods 
    // ... 

    // Now the methods with different behaviour: 
    public String getParameter(String name) { 
     return adjustedParams.get(name) == null ? null : adjustedParams.get(name)[0]; 
    } 

    public Map<String, String[]> getParameterMap() { 
     return adjustedParams; 
    } 

    public Enumeration<String> getParameterNames() { 
     return Collections.enumeration(adjustedParams.keySet()); 
    } 

    public String[] getParameterValues(String name) { 
     return adjustedParams.get(name); 
    } 
    }); 
} 

有超过50种实现方法。他们中的大多数只是原始请求的包装实现。我们只需要四个自定义实现。但是我们必须写下所有这些方法。

因此,请参阅HttpServletRequestWrapper类。这是一个默认的包装器实现,它接受原始请求实例并将接口HttpServletRequest的所有方法实现为调用原始请求的相应方法的简单包装器方法,就像我们上面所做的那样。

通过子类HttpServletRequestWrapper我们只需要用自定义行为覆盖四个参数方法。

private HttpServletRequest adjustParamDates(final HttpServletRequest req) { 
    final Map<String, String[]> adjustedParams = reformatDates(req.getParameterMap()); 
    return new HttpServletRequestWrapper(req) { 
    public String getParameter(String name) { 
     return adjustedParams.get(name) == null ? null : adjustedParams.get(name)[0]; 
    } 

    public Map<String, String[]> getParameterMap() { 
     return adjustedParams; 
    } 

    public Enumeration<String> getParameterNames() { 
     return Collections.enumeration(adjustedParams.keySet()); 
    } 

    public String[] getParameterValues(String name) { 
     return adjustedParams.get(name); 
    } 
    }); 
} 
相关问题