sendRedirect() 不会在 GlassFish 3.1.1 下使用 Servlet 3.0 抛出 IllegalStateException

发布于 2025-01-04 13:23:12 字数 1433 浏览 3 评论 0原文

我在面向 GlassFish 3.1 的 Dynamic Web App 3.0 中有一个带有重写 doGet 方法的 servlet。

我正在学习 OCEJWCD 考试并尝试记住哪些情况会抛出哪些异常。

由于Tomcat 6.0仅支持Servlet 2.5 API,我必须使用Glassfish 3,并且我对以下情况感到非常困惑。

许多旧的来源指出:

servlet 开始写入后立即提交响应 任何内容到输出流。如果您尝试在 响应已提交,您将收到 IllegalStateException 错误。

然而 Servlet 3.0 最终规范第 5.3 节指出:

如果数据已写入响应缓冲区,但未返回 客户端(即响应未提交),数据在 响应缓冲区必须被清除并替换为设置的数据 这些方法。如果响应被提交,这些方法必须抛出 IllegalStateException

是,考虑到 PrintWriter.print() 正在提交响应,为什么这些行不抛出 IllegalStateException

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    String url = "http://someurl.com/";
    PrintWriter out = response.getWriter();
    out.print("This will be written into response buffer");
    response.sendRedirect(url); // sendRedirect() after writing into buffer
}

我必须注意,我能够从 GlassFish 服务器日志中获取异常,我可以清楚地看到 HttpServletRequest.getRequestDispatcher().forward(req,res); 后面跟着一个 HttpServletResponse。 sendRedirect(url); 确实在 GlassFish 容器中抛出 IllegalStateException

I have a servlet with an overridden doGet method in a Dynamic Web App 3.0 targeted to GlassFish 3.1.

I'm studying for OCEJWCD exam and trying to memorize which circumstances throw which exceptions.

Due to Tomcat 6.0 only supporting Servlet 2.5 API, I have to use Glassfish 3 and I'm very confused with following situation.

Numerous old sources state that:

A response is committed as soon as the servlet starts to write
anything to the output stream. If you attempt a re-direct after the
response is committed you will receive an IllegalStateException error.

However Servlet 3.0 Final specification Section 5.3 states:

If data has been written to the response buffer, but not returned to
the client (i.e. the response is not committed), the data in the
response buffer must be cleared and replaced with the data set by
these methods. If the response is committed, these methods must throw
an IllegalStateException

What I want to know is, considering the PrintWriter.print() is committing the response, why don't these lines throw IllegalStateException?

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    String url = "http://someurl.com/";
    PrintWriter out = response.getWriter();
    out.print("This will be written into response buffer");
    response.sendRedirect(url); // sendRedirect() after writing into buffer
}

I have to note that, I am able to fetch exceptions from GlassFish server log, I can clearly see that HttpServletRequest.getRequestDispatcher().forward(req,res); followed by a HttpServletResponse.sendRedirect(url); does indeed throw an IllegalStateException in GlassFish container.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

亽野灬性zι浪 2025-01-11 13:23:12

事实上,PrintWriter.print()可能提交响应。如果缓冲区已满或根本没有缓冲,就会发生这种情况。您可以通过调用 ServletResponse.getBufferSize() 来检查其大小。

ServletResponse.flushBuffer()PrintWriter.flush() 肯定会提交响应。

因此,如果 PrintWriter.print() 正在提交响应,则 HttpServletResponse.sendRedirect() 确实会抛出 IllegalStateException

另请参阅 Servlet 规范,5.1 缓冲 部分。

顺便说一句,没有 RequestDispatcher.dispatch()。 ;)

The fact is that PrintWriter.print() may commit the response. This happens if the buffer is full or if there's no buffering at all. You can check its size by calling ServletResponse.getBufferSize().

ServletResponse.flushBuffer() or PrintWriter.flush() will definitely commit the response.

So if PrintWriter.print() was committing the response, then the HttpServletResponse.sendRedirect() would indeed throw an IllegalStateException.

See also Servlet Specification, section 5.1 Buffering.

And btw., there's no RequestDispatcher.dispatch(). ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文