有两天我试过找出出了什么问题。我在这里读到我应该在代码中添加一个返回,我做到了,我仍然得到
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;
}
答案 0 :(得分:12)
从高级别看,您的具体问题是由于您错误地使用JSP文件而不是Servlet类作为前端控制器而引起的。
从低级别看,您的具体问题是由于JSP在生成HTML代码并将其发送到HTTP响应期间扮演视角技术的角色。响应缓冲区大小默认为2KB。一旦代码到达该行,JSP中的每个HTML和其他模板文本都会立即写入响应。因此,当第一次达到响应缓冲区大小限制时,所有HTTP响应标头和到目前为止编写的HTML代码将被发送到客户端(webbrowser)。换句话说,响应已提交。这是一个不归路。它根本无法从客户端获取已经发送的字节。
重定向基本上在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>
然而,这是bad practice。而是将所有前端控制器和业务逻辑移动到Servlet。然后你的方法是从高级看到正确的。 Java代码不属于JSP文件,而是属于Java类。