【问题标题】:Is it possible to forward or redirect from a servlet filter after the response has been committed?提交响应后是否可以从 servlet 过滤器转发或重定向?
【发布时间】:2011-03-25 08:01:48
【问题描述】:

逻辑是过滤器被命中,条件不成立,所以它通过过滤器链。提交响应后,过滤器被命中,现在条件为真(设置了请求属性)。它进入执行转发,但页面从不转发。我知道这与提交的响应有关,因为我测试了它在第一次到达链之前转发的不同逻辑,并且它确实转发成功。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

    HttpServletRequest httpServletRequest = (HttpServletRequest)request;

    if (some condition equals true) {
        httpServletRequest.getRequestDispatcher("/home.jsp").forward(request, response);
        return;
    } else {
        chain.doFilter(request, response);
    }
}

我的部署描述符中的示例:

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.filters.MyFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
    <dispatcher>REQUEST</dispatcher>  
    <dispatcher>FORWARD</dispatcher> 
</filter-mapping>

【问题讨论】:

    标签: java servlets servlet-filters forward


    【解决方案1】:

    HttpServletResponse 的“已提交”状态实际上是表示响应标头是否已写入底层套接字的一种方式。一个“承诺的”响应已经(至少)写了第一行。由于响应的第一行包含状态代码,因此您无法更改已提交响应的状态代码......这意味着将状态更改为 3xx 进行重定向为时已晚。同样,您不能进行本地转发,因为您已经开始发送响应。

    【讨论】:

      【解决方案2】:

      您可以使用自定义HttpServletResponse 来实现您想要的。您将这个包装好的 HttpServletResponse 传递到过滤器链中。您可以提供存储所有写入请求的本地 OutputStream、存储状态代码和标头的本地变量。回到过滤器后,您可以决定执行重定向或将本地变量的结果从包装器复制回原始 ServletResponse(即设置状态代码和标头并将结果从本地输出流复制到servlet 响应的输出流)。

      编辑:

      有关使用CharResponseWrapper 的代码示例,请参阅Programming Customized Requests and Responses 部分。该示例使用自定义 Writer,但可以轻松将其扩展为 OutputStream。根据您的 Servlet 的使用方式,您需要覆盖 getWriter()getOutputStream() 之一或两者以延迟将任何内容提交到原始响应。此外,您需要覆盖isCommitted() 以返回false,以便可以在过滤器链中随时执行转发。您还需要覆盖 resetBuffer() 以初始化新的 OutputStream/Writer 以在重定向/转发之后存储新内容(包括标头)。

      【讨论】:

      • 您能否根据上面所需的/home.jsp 重定向提供一些sample code?我也遇到了这个问题。谢谢!
      • @DougA 检查我回复中的编辑。这应该总结需要做什么。
      猜你喜欢
      • 2013-08-15
      • 2013-06-25
      • 2014-09-18
      • 1970-01-01
      • 2023-03-17
      • 2011-12-18
      • 2015-09-12
      • 2014-05-09
      • 1970-01-01
      相关资源
      最近更新 更多