在提交响应后,是否可以从servlet过滤器转发或重定向?

7 java servlets forward servlet-filters

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的部署描述符示例:

<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>
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 16

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


sha*_*ams 5

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

编辑:

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