これまでに作成したブックマーク集では、一覧表示、新規登録、アクセスカウント、および登録内容の修正までが行えるようになりました。後は、登録内容の削除が行えるようになれば、ブックマーク集に必要な機能はすべて実装されたことになります。
削除機能を作成するために、ここでは削除用のフォームを表示するdelete_form.jspと、削除処理を行うdelete.jspを新たに作成することにします。いままでに作成したentry_form.jspとupdate.jspに処理の分岐を1つ加えて、同じプログラムで削除機能に対応しても構わないのですが、表示内容と処理内容が大きく異なるため、今回は別のプログラムにすることにしました。このあたりは、開発効率とメンテナンス性を考慮して判断することになります。
まず、一覧表示からブックマークIDを引数として、削除用のフォームを表示するページへアクセスできるように新しく削除用のリンクを作成します。
削除ページでは、登録されている内容の確認用表示と、パスワードの入力を行い、実際の処理を行う削除処理のプログラムへブックマークIDとパスワードを渡します。
削除プログラムでは、パスワードのチェックを行い、パスワードが正しければ実際に削除処理を行い、削除した旨のメッセージを表示します。
登録内容を削除するためのリンクを表示するように、一覧表示用のプログラム(list.jsp)に手を加えます。削除用フォームリンク先は、
delete_form.jsp?bookmarkid=ブックマークID
となります。編集用のリンクを追加したときと同じように、テーブルの1行目に削除用のカラムを1つ追加し、いままでのlist.jspのテーブル作成処理部分に、以下のアンダーラインで書かれた行を追加します。
// テーブル用のHTMLを作成
tableRows += "<tr bgcolor=\"#FFFFFF\"><td align=\"center\" nowrap>" +
"<a href=\"jump.jsp?bookmarkid=" + id + "\">" + title + "</a></td>" +
"<td>" + comment + " ( by "+ nickname + " )</td>"+
"<td align=\"right\">" + count + "</td>" +
"<td nowrap>" + insDate + "</td>" +
"<td align=\"center\"><font size=2>" +
"<a href=\"entry_form.jsp?bookmarkid=" + id + "\">■</a></font></td>" +
"<td align=\"center\"><font size=2>" +
"<a href=\"delete_form.jsp?bookmarkid=" + id + "\">×</a></font></td>" +
"</tr>";
以上の修正で、一覧表示ページに削除用のリンクを表示するカラムが追加されました。
それでは、削除用のフォームを表示するdelete_form.jspを作成します。入力項目はパスワードだけですが、削除する前に登録内容を確認できるように、データベースへアクセスし、タイトル、URL、コメント、登録者名を表示するものとします。削除用フォームを表示するプログラムのコードは次のようになります。
1: <%@ page import="java.sql.*, atmarkit.MyDBAccess"
2: contentType="text/html; charset=euc-jp" %>
3: <%
4: // ブックマーク削除用フォームの表示
5:
6: String bookmark_id = request.getParameter("bookmarkid");
7:
8: // MyDBAccess のインスタンスを生成する
9: MyDBAccess db = new MyDBAccess();
10:
11: // データベースへのアクセス
12: db.open();
13:
14: // 登録済の内容を取得するためのSQL文
15: String sql = "select * from bookmark where bookmarkid=" + bookmark_id;
16:
17: // 登録内容の取得
18: ResultSet rs = db.getResultSet(sql);
19:
20: rs.next();
21: String title = rs.getString("title"); // タイトル名を取得
22: String url = rs.getString("url"); // URLを取得
23: String comment = rs.getString("comment"); // コメントを取得
24: String nickname = rs.getString("nickname"); // 登録者名を取得
25:
26: // 文字コードを変換
27: title = new String(title.getBytes("8859_1"), "EUC_JP");
28: comment = new String(comment.getBytes("8859_1"), "EUC_JP");
29:
30: // データベースへのコネクションを閉じる
31: db.close();
32: %>
33: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
34: <html>
35: <head>
36: <meta http-equiv="Content-Type" content="text/html; charset=euc-jp">
37: <title>登録内容の削除</title>
38: </head>
39: <body>
40: <div>
41: 共有ブックマーク集
42: <br><br>
43: 「登録内容の削除」<br><br>
44: <form method="post" action="delete.jsp">
45: <table border="0" cellspacing="0" cellpadding="0" bgcolor="#000000" width=100%>
46: <tr><td>
47: <table border="0" cellspacing="1" cellpadding="4" width=100%>
48: <tr>
49: <td align="center" bgcolor="#C0C0C0">タイトル</td>
50: <td align="left" bgcolor="#E6E1FF"><%= title %></td>
51: </tr>
52: <tr>
53: <td align="center" bgcolor="#C0C0C0">URL</td>
54: <td align="left" bgcolor="#FFFFFF"><%= url %></td>
55: </tr>
56: <tr>
57: <td align="center" bgcolor="#C0C0C0">コメント</td>
58: <td align="left" bgcolor="#E6E1FF"><%= comment %></td>
59: </tr>
60: <tr>
61: <td align="center" bgcolor="#C0C0C0">登録者名</td>
62: <td align="left" bgcolor="#FFFFFF"><%= nickname %></td>
63: </tr>
64: <tr>
65: <td align="center" bgcolor="#C0C0C0">パスワード</td>
66: <td align="left" bgcolor="#E6E1FF">
67: <input type="password" name="password" size=16>
68: <font size=2>(半角英数)</font>
69: </td>
70: </tr>
71: </table>
72: </td></tr>
73: </table>
74: <br>
75: <input type="hidden" name="bookmarkid" value="<%= bookmark_id %>">
76: <input type="submit" value=" 削除 "> (上記の内容を削除します)
77: </form>
78: <a href="list.jsp">戻る</a>
79: </div>
80: </body>
81: </html>
データベースへアクセスして登録内容を取得する処理は、修正機能の実装でも行ったことなので、特に問題はないでしょう。削除用のフォームでは、パスワードを入力するためのフォームだけを表示することになります。
削除を実行するプログラムへ対象となるブックマークのIDを75行目で hidden パラメータとして渡していることに注意しましょう。
75: <input type="hidden" name="bookmarkid" value="<%= bookmark_id %>">
上記のプログラムを実行した結果は次のようになります。
パスワードを入力して、[削除]ボタンを押すことで、登録内容の削除が行えるようになります。いまの段階では、delete.jspができていないので、削除の処理は行えません。続いて、実際に削除処理を行うdelete.jspを作成します。
削除処理を行う際には、修正処理を行うときと同じように、パスワードのチェックを行います。これには、あらかじめ作成してあるMyUtilクラスのpasswordCheckメソッドを使用します。実際に削除処理を行うプログラムは次のようになります。
1: <%@ page import="java.sql.*, atmarkit.MyDBAccess, atmarkit.MyUtil"
2: contentType="text/html; charset=euc-jp" %>
3: <%
4: // ブックマークを登録する
5:
6: // 入力された引数を取得する
7: String bookmark_id = request.getParameter("bookmarkid");
8: String password = request.getParameter("password");
9:
10: // MyDBAccess のインスタンスを生成する
11: MyDBAccess db = new MyDBAccess();
12:
13: // データベースへのアクセス
14: db.open();
15:
16: if(MyUtil.passwordCheck(db, bookmark_id, password)) { // パスワードが一致した場合
17: String sql = "delete from bookmark where bookmarkid=" + bookmark_id;
18: db.execute(sql);
19: } else { // パスワードが正しくなかった場合
20: db.close();
21: %><jsp:forward page="password_error.jsp" /><%
22: }
23:
24: // データベースへのコネクションを閉じる
25: db.close();
26: %>
27: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
28: <html>
29: <head>
30: <meta http-equiv="Content-Type" content="text/html; charset=euc-jp">
31: <title>削除完了</title>
32: </head>
33: <body>
34: <p>
35: 削除を行いました。
36: <br><br>
37: <a href="list.jsp">一覧へ戻る</a>
38: </body>
39: </html>
削除処理はパスワードが正しかった場合にのみ実行されます。16行目でパスワードのチェックを行い、正しかった場合は引き続き削除処理を行っています。正しくなかった場合は、修正のときと同じようにpassword_error.jspのページへ転送しています。
16: if(MyUtil.passwordCheck(db, bookmark_id, password)) { // パスワードが一致した場合
17: String sql = "update bookmark set delflg=true where bookmarkid=" + bookmark_id;
18: db.execute(sql);
19: } else { // パスワードが正しくなかった場合
20: db.close();
21: %><jsp:forward page="password_error.jsp" /><%
22: }
最後に、削除を行った旨のメッセージを表示し、一覧へ戻るためのリンクを出力します。今回の削除処理では、実際にデータベースからの delete 処理は行わず、削除フラグをtrueにすることで、ブックマーク一覧から削除されたものとして扱っています。これは、誤って消された内容を、管理者権限で後から復元できることを考慮したためです。SQL文は17行目で作成しています。
17: String sql = update bookmark set delflg=true where bookmarkid=" + bookmark_id;
実際にデータベースからデータそのものを削除する場合には、17行目を次のように変更し、delete 文を用います。
17: String sql = "delete from bookmark where bookmarkid=" + bookmark_id;
さて、先ほどの削除用フォームで[削除]ボタンを押した結果は次のようになります。
一覧のページに戻ると、確かに登録内容が削除されたことが確認できます。
以上で、当初予定していた共有ブックマークのすべての機能が実装されました。さらに、アクセスカウント数でソートして表示するオプションや、件数が増えた場合に「前の20件」「次の20件」のようにページを区切る機能なども欲しいところですが、技術的に解説すべき内容は特にないので、今回の連載では解説しません。ご自身で実際にプログラムを作成してみて、余力がありましたらチャレンジしてみてください。
さて、現段階でブックマーク集としての機能の実装は完了しましたが、このままでは新規登録や修正用のフォームに入力される文字列によっては、正しく機能しない場合があります。例えば、悪意を持ったユーザーがコメント欄に“</table>”という文字列を入れた場合、ページの表示がおかしくなってしまいますし、“'”を含んだ文字列が渡された場合には、不適切なSQL文が生成されることになります。悪意を持って、危険なSQL文の生成を試みられるかもしれません。また、入力欄への不適切な入力に留まらず、特定のページへ不適切なパラメータを直接指定してアクセスされるかもしれません(例えばdelete.jsp?bookmarkid=1というURLを指定することで、直接JSPページにパラメータとしてbookmarkid=1の値を渡すことができます)。不特定多数のユーザーが使用することを前提としたWebアプリケーションを作成するには、これらの不適切な入力にもきちんと対応できるように注意が必要です。
次回は、入力された文字列にHTML表示上問題のある文字が含まれている場合や、SQL文を作成する上で問題のある文字が含まれている場合に対処する方法、および、入力文字数のチェックや入力文字の種類をチェックする方法などセキュリティを意識する上で必要となる仕組みを解説します。
Copyright © ITmedia, Inc. All Rights Reserved.