gpt4 book ai didi

java - 为什么我们包装 HttpServletRequest ? api 提供了一个 HttpServletRequestWrapper 但我们从包装请求中得到了什么?

转载 作者:搜寻专家 更新时间:2023-10-31 08:18:49 25 4
gpt4 key购买 nike

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

最佳答案

HttpServletRequest是 HTTP 特定 servlet 请求的接口(interface)。通常,您会在 servlet filters 中获得此接口(interface)的实例或 servlets .

有时您想在某个时候调整原始请求。用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) {
// ???
}

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

所以我们可以做类似的事情。我们创建一个 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。这是一个默认的包装器实现,它采用原始请求实例并将接口(interface) 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);
}
});
}

关于java - 为什么我们包装 HttpServletRequest ? api 提供了一个 HttpServletRequestWrapper 但我们从包装请求中得到了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44182370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com