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



两天来,我一直在努力找出问题所在。我在这里读到我应该在代码中添加一个返回,我做到了,我仍然得到

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

我该如何解决这个问题?

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

<%!
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);
}  
}
%>

类似于这个代码块:

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

但在这个代码块中,它的工作非常完美:

String back = request.getParameter("retrun");
if(back != null)
{
response.sendRedirect("fourm.jsp");
return;
}       

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

从底层来看,您的具体问题是由于JSP作为一种视图技术,在生成HTML代码并将其发送到HTTP响应过程中发挥了作用。响应缓冲区大小默认为2KB。JSP中的每一个HTML和其他模板文本都会在代码到达该行后立即写入响应。因此,当第一次达到响应缓冲区大小限制时,所有HTTP响应标头和迄今为止编写的HTML代码都将发送到客户端(网络浏览器)。换言之,回应是承诺的。这是一个不可回头的地方。根本不可能从客户端取回已经发送的字节。

重定向基本上在HTTP响应上设置一个Location头。为了能够正确地设置这一点,显然还不能提交响应。如果客户端已经发送和检索了所有响应标头,则根本不可能设置新的响应标头。

从底层来看,您可以通过将所有前端控制器和业务逻辑移动到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>

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

最新更新