Javaで詳細画面を作るには?IDでデータを1件取得して表示する流れ|確認問題の回答例
Javaで詳細画面を作るには?IDでデータを1件取得して表示する流れの確認問題の回答例です。IDを渡す流れと、取得したTaskを表示へ渡す流れを区別して確認しましょう。
問題1:表示したい行のIDをリンクへ含める
<a href="task-detail?id=3">詳細</a>
ID=3を指定します。同じ名前の行があっても主キーのIDなら1件を特定できます。また、一覧の表示順が変わってもIDはその行を指します。一覧をJSPで作る場合は、その行のTaskのgetId()をリンクへ入れます。
問題2:1はプレースホルダの番号、idは検索する値
stmt.setInt(1, id);
第1引数の1は、SQLの最初の?を指定しています。第2引数のidは、ServletからModelを経て渡された検索対象のIDです。今回の値は2なので、WHERE id = ?の?に整数2を設定します。1番目の行を検索するという意味ではありません。
問題3:入力不正・0件・SQLエラーは別の結果
- id=abc:ServletのInteger.parseIntで変換できず、NumberFormatExceptionをcatchして400を返す。DAOは呼ばない。
- id=999で該当行なし:DAOのrs.next()がfalseとなりnullが返る。Servletがtask == nullを確認して404を返す。
- tasksテーブルなし:DAOのSQL処理でSQLExceptionが通知され、Modelを経てServletのcatchへ届く。ログに記録して500を返す。
「対象がなかった」と「検索できなかった」を混同しないことが重要です。DAOでSQLExceptionをcatchしてnullを返してしまうと、この実装ではDBの故障を404として扱うことになります。
問題4:JSPを直接開いても、Taskは用意されない
JSPに付けたid=2はリクエストパラメータであり、task属性ではありません。JSPはDBを検索しないため、直接開いてもTaskがなく、この例では404になります。
アプリのパスが/tasks-appなら、/tasks-app/task-detail?id=2へアクセスします。ServletからModel・DAOを呼んでTaskを取得した後、次の処理でJSPへ渡します。
request.setAttribute("task", task);
request.getRequestDispatcher("/task-detail.jsp").forward(request, response);
JSPのgetAttribute(“task”)と、setAttributeの第1引数の名前を一致させます。変数名を同じにするだけでデータが届くわけではありません。