[解決済み] [Solved] java.lang.IllegalStateException: レスポンスがコミットされた後では(forward | sendRedirect | create session)できません。
質問事項
このメソッドは
java.lang.IllegalStateException: レスポンスがコミットされた後は転送できません
と表示され、問題を発見することができません。何かいい方法はないでしょうか?
int noOfRows = Integer.parseInt(request.getParameter("noOfRows"));
String chkboxVal = "";
// String FormatId=null;
Vector vRow = new Vector();
Vector vRow1 = new Vector();
String GroupId = "";
String GroupDesc = "";
for (int i = 0; i < noOfRows; i++) {
if ((request.getParameter("chk_select" + i)) == null) {
chkboxVal = "notticked";
} else {
chkboxVal = request.getParameter("chk_select" + i);
if (chkboxVal.equals("ticked")) {
fwdurl = "true";
Statement st1 = con.createStatement();
GroupId = request.getParameter("GroupId" + i);
GroupDesc = request.getParameter("GroupDesc" + i);
ResultSet rs1 = st1
.executeQuery("select FileId,Description from cs2k_Files "
+ " where FileId like 'M%' and co_code = "
+ ccode);
ResultSetMetaData rsm = rs1.getMetaData();
int cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol1 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol1.addElement(rs1.getObject(j));
}
vRow.addElement(vCol1);
}
rs1 = st1
.executeQuery("select FileId,NotAllowed from cs2kGroupSub "
+ " where FileId like 'M%' and GroupId = '"
+ GroupId + "'" + " and co_code = " + ccode);
rsm = rs1.getMetaData();
cCount = rsm.getColumnCount();
while (rs1.next()) {
Vector vCol2 = new Vector();
for (int j = 1; j <= cCount; j++) {
vCol2.addElement(rs1.getObject(j));
}
vRow1.addElement(vCol2);
}
// throw new Exception("test");
break;
}
}
}
if (fwdurl.equals("true")) {
// throw new Exception("test");
// response.sendRedirect("cs2k_GroupCopiedUpdt.jsp") ;
request.setAttribute("GroupId", GroupId);
request.setAttribute("GroupDesc", GroupDesc);
request.setAttribute("vRow", vRow);
request.setAttribute("vRow1", vRow1);
getServletConfig().getServletContext().getRequestDispatcher(
"/GroupCopiedUpdt.jsp").forward(request, response);
}
解決方法は?
スタートアップにありがちな誤解は、「Scala」の呼び出しは、「Scala」ではなく「Scala」であると考えることです。
forward()
,
sendRedirect()
または
sendError()
は魔法のようにメソッドブロックを終了して "jump" するので、コードの残骸を無視することができます。例えば
protected void doXxx() {
if (someCondition) {
sendRedirect();
}
forward(); // This is STILL invoked when someCondition is true!
}
このように、実はそうではないのです。これらは確かに他のJavaのメソッドと違った振る舞いをすることはありません(
System#exit()
もちろんです)。このとき
someCondition
は、上記の例では
true
を呼び出していることになります。
forward()
の後に
sendRedirect()
または
sendError()
が同じリクエスト/レスポンスにある場合、その確率は
大きい
という例外が発生します。
java.lang.IllegalStateException: レスポンスがコミットされた後は転送できません
もし
if
ステートメントを呼び出すと
forward()
を呼び出した後、その後に
sendRedirect()
または
sendError()
の場合、以下の例外がスローされます。
java.lang.IllegalStateException: レスポンスがコミットされた後に sendRedirect() をコールできない
この問題を解決するには、以下のいずれかの方法を取る必要があります。
return;
ステートメントの後に
protected void doXxx() {
if (someCondition) {
sendRedirect();
return;
}
forward();
}
... あるいは、elseブロックを導入する。
protected void doXxx() {
if (someCondition) {
sendRedirect();
} else {
forward();
}
}
コードの中にある根本的な原因を突き止めるには、まず最初に
forward()
,
sendRedirect()
または
sendError()
メソッドブロックを終了したり、コードの残りをスキップしたりすることなく これは、特定のコード行の前にある同じサーブレット内だけでなく、 特定のサーブレットの前に呼び出されたサーブレットやフィルタ内でも可能です。
の場合
sendError()
レスポンス・ステータスを設定することが唯一の目的である場合には
setStatus()
の代わりに
もう一つの原因として考えられるのは、サーブレットがレスポンスに書き込む際に
forward()
が呼び出されるか、まったく同じメソッドで呼び出されたことがあります。
protected void doXxx() {
out.write("some string");
// ...
forward(); // Fail!
}
レスポンスバッファーのサイズは、ほとんどのサーバーでデフォルトが2KBなので、2KB以上書き込むと、コミットされ
forward()
も同じように失敗します。
java.lang.IllegalStateException: レスポンスがコミットされた後では転送できません
解決策は明らかです。サーブレットでレスポンスに書き込まないようにすればいいのです。それはJSPの責任です。次のようにリクエスト属性を設定するだけです。
request.setAttribute("data", "some string")
で、それをJSPで次のように表示します。
${data}
. 参照
サーブレットウィキのページ
を使えば、サーブレットの正しい使い方を知ることができます。
もう一つの原因として考えられるのは、サーブレットがファイルのダウンロードをレスポンスに書き込んだ後、例えば
forward()
が呼び出されます。
protected void doXxx() {
out.write(bytes);
// ...
forward(); // Fail!
}
これは技術的に不可能です。を削除する必要があります。
forward()
の呼び出しがあります。エンドユーザは現在開いているページに留まることになります。ファイルダウンロード後に実際にページを変更するつもりであれば、ファイルダウンロードのロジックをターゲットページのページロードに移動する必要があります。
さらにもう一つの原因として考えられるのは
forward()
,
sendRedirect()
または
sendError()
メソッドは、JSP ファイルに埋め込まれた Java コードを介して、昔ながらの方法で呼び出されます。
<% scriptlets %>
という慣習がありました。
2001年以降、公式に推奨されていない
. 例えば
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
...
<% sendRedirect(); %>
...
</body>
</html>
ここで問題なのは、JSPが内部でテンプレートテキスト(つまりHTMLコード)を即座に書き込むために
out.write("<!DOCTYPE html> ... etc ...")
に遭遇するとすぐに したがって、これは前のセクションで説明したのと本質的に同じ問題です。
解決策は明らかで、JSPファイルにJavaのコードを書かないことです。それは、ServletやFilterのような通常のJavaクラスの責任です。以下も参照してください。 サーブレットウィキページ を使えば、サーブレットの正しい使い方を知ることができます。
こちらもご覧ください。
関連性のないもの は、あなたの具体的な問題に、あなたのJDBCコードは、リソースをリークしている。それも解決してください。ヒントとしては JDBCで接続、ステートメント、結果セットを閉じる頻度はどのくらいがよいですか?
関連
-
[解決済み] [Solved] java.lang.IllegalStateException: レスポンスがコミットされた後では(forward | sendRedirect | create session)できません。
-
[解決済み] HTTPServletRequest getParameterMap() と getParameterNames の比較
-
[解決済み] HTTPステータス 405 - HTTPメソッドGETは、このURLではサポートされていません [重複].
-
[解決済み】サーブレットベースのアプリケーションで、設定リソースファイルをどこに置き、どのように読み込むか?
-
[解決済み] サーブレットマッピングのurlパターンにおける/と/*の違いについて
-
[解決済み] WARでアノテーションを使用してサーブレットフィルタの実行順序を定義する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Solved] java.lang.IllegalStateException: レスポンスがコミットされた後では(forward | sendRedirect | create session)できません。
-
[解決済み] レスポンスがコミットされた後に sendRedirect() を呼び出せない問題を修正する方法は?[重複]。
-
[解決済み] java.lang.IllegalStateException on response.SendRedirect("Location") [duplicate].
-
[解決済み] HTTPServletRequest getParameterMap() と getParameterNames の比較
-
[解決済み] HTTPステータス 405 - HTTPメソッドGETは、このURLではサポートされていません [重複].
-
[解決済み】サーブレットベースのアプリケーションで、設定リソースファイルをどこに置き、どのように読み込むか?
-
[解決済み] サーブレットマッピングのurlパターンにおける/と/*の違いについて
-
[解決済み] WARでアノテーションを使用してサーブレットフィルタの実行順序を定義する方法