为什么我们包装HttpServletRequest?该API提供了一个HttpServletRequestWrapper,但是从包装请求中我们可以得到什么呢? [英] Why do we wrap HttpServletRequest ? The api provides an HttpServletRequestWrapper but what do we gain from wrapping the request?

查看:62
本文介绍了为什么我们包装HttpServletRequest?该API提供了一个HttpServletRequestWrapper,但是从包装请求中我们可以得到什么呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用HttpServletRequestWrapper包装HttpServletRequest的目的是什么?通过这样做,我们有什么好处?

What is the purpose of wrapping an HttpServletRequest using an HttpServletRequestWrapper ? What benefits do we gain from doing this ?

推荐答案

HttpServletRequest 是HTTP特定servlet请求的接口.通常,您可以在 servlet过滤器中获得此接口的实例或 servlet .

HttpServletRequest is an interface for a HTTP specific servlet request. Typically you get instances of this interface in servlet filters or servlets.

有时候您想调整原始请求.使用 HttpServletRequestWrapper 可以包装原始请求并覆盖一些方法,使其行为略有不同.

Sometimes you want to adjust the original request at some point. With a HttpServletRequestWrapper you can wrap the original request and overwrite some methods so that it behaves slightly different.

示例:

您有一堆servlet和JSP,它们期望某些请求参数采用某种格式.例如.日期格式为yyyy-MM-dd.

You have a bunch of servlets and JSPs which expect some request parameters in a certain format. E.g. dates in format yyyy-MM-dd.

现在,还需要以其他格式来支持日期,例如具有相同功能的dd.MM.yyyy.假设没有最新的中心字符串功能(这是一个继承的遗留应用程序),则必须在Servlet和JSP中查找所有位置.

Now it is required to support the dates also in a different format, like dd.MM.yyyy with the same functionality. Assuming there is no central string to date function (it's an inherited legacy application), you have to find all places in the servlets and JSPs.

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

As an alternative you can implement a servlet filter. You map the filter so that all requests to your servlets and JSPs will go through this filter.

过滤器的目的是检查日期参数的格式,并在必要时将其重新格式化为旧格式. Servlet和JSP始终以预期的旧格式获取日期字段.无需更改它们.

The filter's purpose is to check the date parameters' format and reformat them to the old format if necessary. The servlets and JSPs get the date fields always in the expected old format. No need to change them.

这是您的过滤器的骨架:

This is the skeleton of your filter:

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

我们接受原始请求,并在方法adjustParamDates()中处理请求并将其传递给过滤器链.

We take the original request and in method adjustParamDates() we manipulate the request and pass it down the filter chain.

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

Now, how would we implement adjustParamDates()?

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

我们需要接口HttpServletRequest的新实例,其行为与原始实例req完全相同.但是,四个方法getParameter()getParameterMap()getParameterNames()getParameterValues()不适用于原始参数,但不适用于调整后的参数集.接口HttpServletRequest的所有其他方法的行为应与原始方法相同.

We need a new instance of interface HttpServletRequest which behaves exactly like the original instance req. But the four methods getParameter(), getParameterMap(), getParameterNames(), getParameterValues() shouldn't work on the original parameters but on the adjusted parameter set. All other methods of interface HttpServletRequest should behave like the original methods.

所以我们可以做类似的事情.我们创建HttpServletRequest的实例并实现所有方法.通过调用原始请求实例的相应方法,大多数方法实现都非常简单:

So we can do something like that. We create an instance of HttpServletRequest and implement all methods. Most method implementations are very simple by calling the corresponding method of the original request instance:

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多种方法可以实现.它们中的大多数只是原始请求的包装器实现.我们只需要四个自定义实现.但是我们必须写下所有这些方法.

There are more than 50 methods to implement. Most of them are only wrapper implementations to the original request. We need only four custom implementations. But we have to write down all these methods.

因此,将类HttpServletRequestWrapper考虑在内.这是默认的包装器实现,它采用原始请求实例,并将接口HttpServletRequest的所有方法实现为调用原始请求的相应方法的简单包装器方法,就像我们上面所做的那样.

So here comes the class HttpServletRequestWrapper into account. This is a default wrapper implementation which takes the original request instance and implements all methods of interface HttpServletRequest as simple wrapper methods calling the corresponding method of the original request, just as we did above.

通过子类化HttpServletRequestWrapper,我们只需要用自定义行为覆盖这四个param方法.

By subclassing HttpServletRequestWrapper we only have to overwrite the four param methods with custom behaviour.

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);
    }
  });
}

这篇关于为什么我们包装HttpServletRequest?该API提供了一个HttpServletRequestWrapper,但是从包装请求中我们可以得到什么呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆