Java J2EE:在此场景下理解isCommitted和过滤器
我正在处理一个筛选器,此代码无法执行/response.write(如果请求中涉及“转发”)。但是,对于简单地向用户发送HTML内容的基本servlet来说,它工作得很好。如何使用此代码处理“转发” 例如,下面是一个过滤器,它简单地捕获文本内容并尝试操作该内容Java J2EE:在此场景下理解isCommitted和过滤器,java,servlets,Java,Servlets,我正在处理一个筛选器,此代码无法执行/response.write(如果请求中涉及“转发”)。但是,对于简单地向用户发送HTML内容的基本servlet来说,它工作得很好。如何使用此代码处理“转发” 例如,下面是一个过滤器,它简单地捕获文本内容并尝试操作该内容 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOExcept
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:
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);
}
}
公共类TestCommitServlet2扩展了HttpServlet{
私有静态最终长serialVersionUID=1L;
@凌驾
受保护的void doGet(HttpServletRequest-req,HttpServletResponse-resp)抛出ServletException,IOException{
最终PrintWriter out=resp.getWriter();
分别为setContentType(“文本/html”);
out.println(“v-1)测试”);
}
@凌驾
受保护的void doPost(最终HttpServletRequest请求、最终HttpServletResponse响应)抛出ServletException、IOException{
doGet(需求、响应);
}
}
Tl;dr:如果(!commit2){代码在没有它的情况下工作,我是否必须进行此调用。在此代码下,我如何避免响应已提交或非法状态异常(在Response.getWriter().write(res)行附近)
有关此问题的更多信息,请参见:
我正在使用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
这表明筛选器根本不适用于此转发的请求
所以,我记得有些过滤器可以在不同的DispatcherType中工作,如FORWARD、INCLUDE、ERROR、ASYNC和commong请求,我决定将过滤器声明更改为
@WebFilter(filterName = "/MyFilter", urlPatterns = { "/TestCommitServlet2" }, dispatcherTypes = {
DispatcherType.FORWARD, DispatcherType.REQUEST })
public class MyFilter implements Filter {
然后,当我跳过servlet TestCommitServlet时,我得到:
(v-1)testing
Button
com.koitoer.CharResponseWrapper@1b3bea22
上面显示过滤器现在应用于转发请求
另外,如果(!commit2){代码仍然有效,那么如果我删除了的行或注释行,那么就不会出现非法状态异常,因为请求需要通过调用doChain方法的过滤器
还有一个注意事项,如果您尝试使用此替换响应的内容
responseWrapper.toString().replaceAll
由于responseWrapper.toString()返回如下内容,所以您做得不对CharResponseWrapper@5b5b6746,而不是内容,如果要修改响应,请使用从HttpServletResponseWrapper扩展而来的包装器,并重写正确的方法来操作outpustream。我使用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
这表明筛选器根本不适用于此转发的请求
所以,我记得有些过滤器可以在不同的DispatcherType中工作,如FORWARD、INCLUDE、ERROR、ASYNC和commong请求,我决定将过滤器声明更改为
@WebFilter(filterName = "/MyFilter", urlPatterns = { "/TestCommitServlet2" }, dispatcherTypes = {
DispatcherType.FORWARD, DispatcherType.REQUEST })
public class MyFilter implements Filter {
然后,当我跳过servlet TestCommitServlet时,我得到:
(v-1)testing
Button
com.koitoer.CharResponseWrapper@1b3bea22
上面显示过滤器现在应用于转发请求
另外,如果(!commit2){代码仍然有效,那么如果我删除了的行或注释行,那么就不会出现非法状态异常,因为请求需要通过调用doChain方法的过滤器
还有一个注意事项,如果您尝试使用此替换响应的内容
responseWrapper.toString().replaceAll
由于responseWrapper.toString()返回如下内容,所以您做得不对CharResponseWrapper@5b5b6746,而不是内容,如果要修改响应,请使用从HttpServletResponseWrapper扩展而来的包装器,并重写正确的方法来操作outpustream。我使用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
这表明筛选器根本不适用于此转发的请求
所以,我记得有些过滤器可以在不同的DispatcherType中工作,如FORWARD、INCLUDE、ERROR、ASYNC和commong请求,我决定将过滤器声明更改为
@WebFilter(filterName = "/MyFilter", urlPatterns = { "/TestCommitServlet2" }, dispatcherTypes = {
DispatcherType.FORWARD, DispatcherType.REQUEST })
public class MyFilter implements Filter {
然后,当我跳过servlet TestCommitServlet时,我得到:
(v-1)testing
Button
com.koitoer.CharResponseWrapper@1b3bea22
上面显示过滤器现在应用于转发请求
另外,如果(!commit2){代码仍然有效,那么如果我删除了的行或注释行,那么就不会出现非法状态异常,因为请求需要通过调用doChain方法的过滤器
还有一个注意事项,如果您尝试使用此替换响应的内容
responseWrapper.toString().replaceAll
由于responseWrapper.toString()返回如下内容,所以您做得不对CharResponseWrapper@5b5b6746,而不是内容,如果要修改响应,请使用从HttpServletResponseWrapper扩展而来的包装器,并重写正确的方法来操作outpustream。我使用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
这表明筛选器根本不适用于此转发的请求
所以,我记得有些过滤器可以在不同的DispatcherType中工作,如FORWARD、INCLUDE、ERROR、ASYNC和commong请求,我决定将过滤器声明更改为
@WebFilter(filterName = "/MyFilter", urlPatterns = { "/TestCommitServlet2" }, dispatcherTypes = {
DispatcherType.FORWARD, DispatcherType.REQUEST })
public class MyFilter implements Filter {
然后,当我跳过servlet TestCommitServlet时,我得到:
(v-1)testing
Button
com.koitoer.CharResponseWrapper@1b3bea22
上面显示过滤器现在应用于转发请求
如果我删除了