J2EE:在这种情况下理解isCommitted和Filters

时间:2014-02-03 23:29:12

标签: java servlets

我正在处理过滤器,如果请求中涉及“转发”,则此代码无法执行/ response.write。但它适用于简单地将HTML内容传递给用户的基本servlet。如何使用此代码解决“转发”问题。

例如,以下是简单捕获文本内容并尝试操作该内容的过滤器。

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;           
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpSession session = request.getSession(false);                
        CharResponseWrapper responseWrapper = new CharResponseWrapper((HttpServletResponse) response);
        chain.doFilter(request, responseWrapper);       
                final boolean commit1 = responseWrapper.isCommitted();           
                final boolean commit2 = response.isCommitted();             
            if (!commit2) {
                final String res = responseWrapper.toString().replaceAll("(?i)</form>", "<input type=\"hidden\" name=\"superval\" value=\""+superval"\"/></form>");             
                response.getWriter().write(res);                        
            }
        return;

    }

... 这适用于大多数基本servlet,目标是使用“replaceAll”。

现在,如果我创建一个带有'forward'的servlet代码不起作用,它会在'if(!commit2)'的行中失败,因为该流已经明确提交了吗?

例如,如果我向此servlet发出请求并将过滤器绑定到此servlet,则过滤器不会完全执行。

public class TestCommitServlet extends HttpServlet {    
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        
        req.getRequestDispatcher("TestCommitServlet2").forward(req, resp);
    }    
    @Override    
    protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

这是我转发的servlet:

public class TestCommitServlet2 extends HttpServlet {    
    private static final long serialVersionUID = 1L;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        final PrintWriter out = resp.getWriter();
        resp.setContentType("text/html");
        out.println("<html><body>(v-1)testing<form action='test'><input type='submit' value='Run' /> </form></body></html>");             
    }    
    @Override    
    protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

Tl; dr :我是否必须进行此调用'if(!commit2){'代码在没有它的情况下正常工作。在此代码下,我将如何避免已提交的响应或IllegalStateExceptions(在response.getWriter()。write(res)行周围;

有关此问题的更多信息:

https://codereview.stackexchange.com/questions/41260/capturing-content-within-a-j2ee-filter-and-then-replacing-this-text-request-for

1 个答案:

答案 0 :(得分:3)

我正在使用Servlet API 3.0来检查这种情况。 我发现的是以下内容。当我调用TestCommitServlet2时,使用servlet和过滤器的代码,我能看到以下输出。

http://localhost:8080/Question/TestCommitServlet2

(v-1)testing
Button here
com.koitoer.CharResponseWrapper@5b5b6746

当我调用servlet TestCommitServlet时,我能看到以下内容。

http://localhost:8080/Question/TestCommitServlet
(v-1)testing
Button here

这表明过滤器根本不适用于此转发请求。

所以,我记得有些过滤器可以在不同的DispatcherTypes中作为FORWARD,INCLUDE,ERROR,ASYNC和commong REQUEST,我决定将过滤器声明更改为。

@WebFilter(filterName = "/MyFilter", urlPatterns = { "/TestCommitServlet2" }, dispatcherTypes = {
        DispatcherType.FORWARD, DispatcherType.REQUEST })
public class MyFilter implements Filter {

然后,当我通过servlet TestCommitServlet执行GET时,我得到了:

(v-1)testing
 Button
com.koitoer.CharResponseWrapper@1b3bea22

以上显示Filter现在已应用于转发请求。

此外,如果我删除或注释 if(!commit2){代码的行仍然有效,那么没有IllegalStateException,因为请求需要传递调用doChain方法的过滤器。< / p>

如果您尝试使用此替换响应的内容,请注意更多。

responseWrapper.toString().replaceAll

你做错了,因为responseWrapper.toString()返回类似这个CharResponseWrapper @ 5b5b6746的内容,而不是内容,如果你想修改响应使用从HttpServletResponseWrapper扩展的Wrapper并覆盖正确的方法来操纵outpustream。