java.lang.IllegalStateException:提交响应后无法调用 sendRedirect()

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12693975/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 09:51:02  来源:igfitidea点击:

java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed

javajsp

提问by Johnathan Nardia

For two days I have tried find out what went wrong. I read here that i should add a return into the code, and I did it, and i still get

两天来,我试图找出出了什么问题。我在这里读到我应该在代码中添加一个返回,我做到了,我仍然得到

java.lang.IllegalStateException: Cannot call sendRedirect() 
     after the response has been committed, Error.

How can I solve this problem?

我怎么解决这个问题?

It happens every time I connect to the database. This is the connect method:

每次我连接到数据库时都会发生。这是连接方法:

<%!

public  void connect()
{
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String dbURL = "jdbc:mysql://localhost:3306/moti";
            String user = "root";
            String password = "j3o4h5n6y7";
            con =  DriverManager.getConnection(dbURL, user, password);  
            statement = con.createStatement();
        }
        catch(Exception ex) {
            throw new Error(ex);
        }  
}
%>

like in this code block :

就像在这个代码块中一样:

            String post = request.getParameter("send");
            if(post != null )
            {
                    connect();
                    statement.execute(add);
                    con.close();
                    response.sendRedirect("fourm.jsp");
                    return;

            }

but in this code block its work perfectly :

但在此代码块中,它的工作完美无缺:

    String back = request.getParameter("retrun");

    if(back != null)
    {

        response.sendRedirect("fourm.jsp");
        return;
    }       

回答by BalusC

From high level seen, your concrete problem is caused because you're incorrectly using a JSP file instead of a Servletclass as a front controller.

从高层来看,您的具体问题是由于您错误地使用 JSP 文件而不是Servlet类作为前端控制器而引起的。

From low level seen, your concrete problem is caused because JSP plays as being a view technology a role during generating and sending HTML code to the HTTP response. The response buffer size defaults to 2KB. Every HTML and other template text in the JSP is immeditatelywritten to the response once the code reaches that line. So when the response buffer size limit is reached for the first time, then all HTTP response headers and the so far written HTML code will be sent to the client (the webbrowser). In other words, the response is committed. This is a point of no return. It's simply not possible to take the already-sent bytes back from the client.

从底层来看,您的具体问题是因为 JSP 在生成 HTML 代码并将其发送到 HTTP 响应期间充当视图技术的角色。响应缓冲区大小默认为 2KB。一旦代码到达该行,JSP 中的每个 HTML 和其他模板文本都会立即写入响应。因此,当第一次达到响应缓冲区大小限制时,所有 HTTP 响应标头和到目前为止编写的 HTML 代码都将发送到客户端(网络浏览器)。换句话说,响应已提交。这是一个不归路。根本不可能从客户端取回已经发送的字节。

A redirect basically sets a Locationheader on the HTTP response. To be able to properly set this, the response must obviously not be committed yet. It's simply not possible to set a new response header if they are all already been sent and retrieved by the client.

重定向基本上Location在 HTTP 响应上设置一个标头。为了能够正确设置它,响应显然必须尚未提交。如果客户端都已发送和检索它们,则根本不可能设置新的响应标头。

From low level seen, you can solve your concrete problem by moving all the front controller and business logic to the far top of the JSP file so that it's executed long before the first HTML code is ever been sent. This way you eliminate the risk that the response is committed before your front controller and business logic is finished.

从底层来看,您可以通过将所有前端控制器和业务逻辑移到 JSP 文件的最顶部来解决具体问题,以便在发送第一个 HTML 代码之前很久就执行它。通过这种方式,您可以消除在前端控制器和业务逻辑完成之前提交响应的风险。

<%@page pageEncoding="UTF-8" %>
<%
    // Write business code here.
%>
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Some</title>
    </head>
    <body>
        ... (no controller/business logic here! just pure presentation)
    </body>
</html>

However, this is a bad practice. Rather move all that front controller and business logic into a Servlet. Then your approach is from high level seen correct. Java code doesn't belong in JSP files, but in Java classes.

然而,这是一个不好的做法。而是将所有前端控制器和业务逻辑移动到Servlet 中。那么你的方法从高层看是正确的。Java 代码不属于 JSP 文件,而是属于 Java 类。