我正在处理过滤器,如果请求中涉及“转发”,则此代码无法执行/ 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)行周围;
有关此问题的更多信息:
答案 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。