JSPを用いた オンラインスケジュール 管理システム 法政大学 4-D 国際文化学部 国際文化学科 00G0310 杉山 佳弘 はじめに 近年、自分のパソコンや、電子手帳等でスケジュールを管理する方法がよく 利用されるようになった。また、学校や会社など、あるグループ内における共 通のスケジュールをWeb上で見られるようにするということも最近では頻繁 に行われている。 しかしそれでは、グループ内における共同のスケジュールと個人用のスケジ ュールを、それを見た人が同時にチェックすることができず、いちいち自分個 人のスケジュール帳と照らし合わせなければならない。また、メンバーはグル ープ用のスケジュール帳にいつ予定が入るかわからないので、それをこまめに チェックしなければならない。 このため、本研究では、インターネット上で個人用とグループ用のスケジュ ールを一つのカレンダーで見ることができ、また、誰でもグループ用のスケジ ュールに書き込むことの出来るシステムを構築することにした。 本システムの特徴は、メンバーの誰かがグループ用のスケジュールを書き込ん だ時、自動的にメンバー全員にその報告がメールで出され、こまめにチェック しなくても、いつ更新されたかがわかる。また、メンバーなら誰でも個人用と グループ用のスケジュール二つを区別して書き込むことが出来る。これにより、 イベントの開催等を一人ずつメールで報告するといった手間が省け、より簡単 に情報の伝達が出来る。 作成動機 個人のためだけのスケジュール帳ではなく、仲間内や、会社、学校などにお ける、限られたメンバーだけの共通のスケジュール帳があれば、それぞれの日 程を合わせて、集合時間や、集合場所などの決定を容易にし、また、そのグル ープの交流を深めるためのいい媒体になると思ったため。また、集まりなどの 予定が決定した場合自動的にメールが配信され、メンバーが予定事項と決定事 項の区別を簡単にでき、また、決定した事項をいち早くメンバーに教えること で、他の予定が入らないようにすることができると便利だと思ったため。 システムの概要 このシステムは、大学でいうとゼミやサークルのような団体に所属するメン バーがスケジュールを管理するために使用するためのシステムである。 (私の場 合はゼミのメンバーで登録した。) このシステムを使用することにより、その団体に所属する全てのメンバーが 各々の個人用のスケジュールとその団体のメンバー全員に共通のスケジュール 両方を一つのカレンダー形式の画面で確認することができ、またそのスケジュ ール表にWEB上から簡単にスケジュールの新規追加・編集・削除ができる。 スケジュールを新規追加する場合は、そのスケジュールが個人用であるか、団 体に所属するメンバー全員に共通のものであるかを、区別し、それがメンバー 全員に共通のスケジュールの場合は、スケジュール表に書き込まれる際に自動 的にメールによりメンバー全員に知らせることができる。 このシステムには機能として、大きく3つの機能がある。一つ目が、前述し たスケジュールを表示し、それにスケジュールを追加・編集・削除が出来、さ らにそのスケジュールが個人用かメンバー用かを区別し、それがメンバー用の 場合はメンバー全員にスケジュールが書き込まれたことを自動的にメールで連 絡するという機能。 ここでの個人用とメンバー用のスケジュールというのは、次にユーザーの情 報を変更するための機能。3 つ目がスケジュールを検索して表示する機能である。 下にこのシステムの主な特徴を挙げる。 ○WEB上で見ることができる ○スケジュールの、新規追加、編集、削除 ○メンバー用と個人用の2種類のスケジュール ○個人情報の編集 ○パスワードと ID による認証 ○スケジュール入力時のメールによる自動連絡 システムの基本仕様 ①スケジュールの表示、新規追加、編集・削除 1.TOP画面から自分のユーザー名と、表示するスケジュールの年月を選 択し、「スケジュール表示」ボタンを押しスケジュール表示画面に移り、 自分のスケジュールを表示する。 ○データベースから、ユーザー情報を取得し、ユーザーを選択。 ○表示するカレンダーの年月を選択。 ○ユーザー情報の変更とスケジュールの検索画面へとぶボタンの表示。 (TOP画面) 2.スケジュールの新規追加をする場合は、日付の数字をクリック、編集・ 削除をする場合は、スケジュール名をクリックする。 3. スケジュール内容(スケジュールの日付、開始時刻、終了時刻、用件、 場所・行き先)を入力し、個人用スケジュールかメンバー用スケジュー ルにチェックを入れる。スケジュールの削除を行う場合は「削除」の欄 にチェックを入れる。入力がすんだら「OK」ボタンを押し、スケジュ ―ル表示画面に戻り、スケジュールが変更されているか確認する。 また、メンバー用スケジュールを追加した場合は登録されているメン バー全員にメールが自動的に送られ、メンバー用スケジュールが追加さ れたことを伝える。 この動作を繰り返し、スケジュールをカレンダーに入れていく。 ②ユーザー情報の変更 1.TOP画面の「ユーザー 情報の変更」ボタンをクリッ クする。 2.ユーザー名とパスワ ードを入力し、「OK」ボタ ンをクリックしてユーザー 情報変更画面へいく。 3.パスワード、メールアドレス、所属ゼミ、電話番号の変更したい部 分を変更し、「変更」ボタンをクリックして、結果表示画面へいく。 4. 「もどる」をクリックし、ユーザー情報画面へ戻り、情報が更新され ているかを確認する。 ③スケジュールの検索 1.TOP画面で「検索する」ボタンをクリックする。 2.スケジュールを検索したい人のユーザー名を選択する。 3.検索したいスケジュールのキーワードを入力する。 4.「検索」ボタンをクリックする。 5.検索結果表示画面へいく。 システム構成 使用ツール 使用しているものは、JSP、Java Script、Access、Tomcat である。 JSPはHTMLファイルの中に Java プログラムをそのまま埋め込めるとい う点で、HTML言語と Java プログラムを併用するのに有利であるため使用し た。Access はデータベースソフトとして最も一般的で初心者の私でも比較的利 用しやすかったため用いた。Tomcat は JSP を処理するために必要なアプリケ ーションサーバである。 ○JSPとは Java 言語を利用して Web サーバで動的に Web ページを生成し、クライアントに送 信する技術。HTML ファイルの中に Java プログラムを埋め込んでおき、クライアント の要求に応じてプログラムを実行、処理結果のみをクライアントに送信する。結果は通 常の HTML 形式になるため、Web ブラウザに特殊な機能を組みこむことなく Web ア プリケーションを構築できる。Microsoft 社の IIS の拡張機能 ASP に似た技術だが、 ASP が(ほぼ)IIS 専用なのに対して、JSP は様々な Web サーバ用の実行環境が用意さ れており、また、特殊なスクリプト言語を覚えることなく、Java 言語をそのまま使え るという利点がある。 ○Java Script とは Java 言語をベースに Sun Microsystems 社と Netscape Communications 社が開発したスク リプト言語(簡易プログラミング言語)。従来は印刷物のような静的な表現しかできなかった Web ページに、動きや対話性を付加することを目的に開発された。Netscape 社や Microsoft 社の Web ブラウザに搭載されている。Microsoft 社の Web サーバ IIS 上で動作させることもで き、サーバ上でスクリプトを実行して動的に HTML 文書を生成することができる。また、WSH を 利用して Windows 95/98 や Windows NT 上で従来より強力なバッチ処理を行なうこともできる。 Netscape 社による実装と Microsoft 社による実装には微妙な違いがあったため、両社が参加 して ECMA によって ECMAScript として標準化された。 ○Access とは DBMS:データベース管理システム。コンピュータで大量のデータを管理運用するため のさまざまな機能を持ち合わせたソフトウェア。最も一般的なデータベース用ソフトウ ェアで、初心者でも比較的使用しやすい。 ○Tomcat とは Jakarta プロジェクトのサブプロジェクトとして開発されているオープンソースのソフトウェアで、 は単独でWebサーバとし て動作することも可能だが、Apache や IIS のプラグインと動作できるようになっており、実際に はプラグインとしての利用が主流である。Tomcat は主な UNIX 系 OS や Windows、Mac OS X などで動作する。Tomcat は Sun Microsystems 社から Java サーブレット・JSP のリファレンス 実装として認められたソフトウェアで、利用者も非常に多い。Apache Software Lisence という ライセンスに基づいて公開されており、誰でも自由かつ無償で利用・改変・再配布できる。 (図①) Java サーブレット・JSP を処理するアプリケーションサーバ。Tomcat データベース データベースには Access というソフトを使用していることは前述したが、本 システムでは図①にあるようにこの Access を用いて2種類のデータベースを使 用している。 1 つ目は、登録されているメンバーのユーザー名、パスワード、所属ゼミ、メ ールアドレス、電話番号等のユーザーに関する情報を格納しているユーザーデ ータベース。もう一つがスケジュールの日時や、開始時刻、終了時刻、用件、 場所・行き先等のスケジュールに関する情報を格納したスケジュールデータベ ースである。 ユーザーデータベース ・ 一人一人のユーザーにそれぞれ通し番号で ID がふられていく ・ 本システムでは extension を電話番号として使用 ・ (authority と idnumber はさらに多くの機能を付けるときに使用するため にある。ちなみに、authority はゼミを番号で判別するために使用するはず であった。idnumber はゼミ以外で別のグループ分けも併用する場合のグル ープ判別のために使用する予定であった。) スケジュールデータベース ・shainID がユーザーデータベースの ID と対応している システムの流れ 図①にあるように初めの TOP 画面でまずスケジュールを表示したいユーザーの 選択を行う。このときユーザー名の一覧を表示するためにユーザーデータベー スからユーザーの情報を取得する。ここでユーザー名を選択し、スケジュール の表示画面にうつる時、選択したユーザーの情報も取得したままの状態で画面 を移動する。 スケジュール表示画面では先程取得したユーザーの情報をもとにそのユーザ ーのスケジュール情報をスケジュールデータベースから取得し、画面に出力す る。 スケジュール編集画面では、ユーザーが入力した情報をスケジュールデータ ベースへ登録・更新する。 クライアント、JSP、Access の関係 (図②) ①. ユーザー(クライアント)からスケジュールの表示などの要求が送信される。 ②. ユーザーからの要求を受け付け、JSPでの処理を経て、データベースへの 検索/登録/更新処理が行われる。 ③. データベースから処理の結果が返される。 ④. JSPによりフォームを生成し、ユーザーに返す。 プログラム構造 1.schedule.jsp ○TOP 画面の表示 ・ 表示するスケジュールの年月を選択するためのプルダウンメニューの 表示 ・ スケジュールを表示するユーザーを選択するためのユーザー名の一覧 をユーザーデータベースから取得し、プルダウンメニューで表示 ・ スケジュール表示画面へのリンクボタンの表示 ・ ユーザー情報変更画面へのリンクボタンの表示 ・ スケジュール検索画面へのリンクボタンの表示 ○contentType を日本語の Shift_JIS に設定 ○page ディレクティブで必要なパッケージやクラスをインポートする。 ○sql パッケージはデータベースアクセスに使用するのに必要なパッケー ジ。 ○Date クラスは日付などの情報を取得するのに必要なパッケージ。 ○GregorianCalendar クラスはカレンダー作成に有効なメソッドが多く含 まれているパッケージ。 <%@ page contentType="text/html;charset=Shift_JIS" %> <%@ page import="java.sql.*" %> <%@ page import="java.util.*" %> <%@ page import="java.util.Date,java.util.GregorianCalendar" %> ○ ユーザーデータベース(user.mdb)に接続する Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection connection=DriverManager.getConnection("jdbc:odbc:user","",""); Statement statement=connection.createStatement(); ○ ユーザーデータベースからユーザー名を取得し、プルダウンメニューで一 覧表示する ・ORDER BY username で検索結果を名前順にソートする。 ・while 文で<OPTION>タグを使用してユーザー1人ずつの名前 userName を表示し、それがクリックされたときにパラメータとして処理プログラム に渡される VALUE として ID を埋め込んである。 ・statement と connection を close()してデータベースとの接続を閉じる。 <SELECT NAME="userID"> メンバー選択--</OPTION> <OPTION VALUE="0">-<% 検索結果を名前順にソート // String qStr="SELECT * FROM table1 ORDER BY ID"; ResultSet rs=statement.executeQuery(qStr);//executeQuery は検索実行 String userID; String userName; String userAuthority; while(rs.next()) { userID=rs.getString("ID"); userName=rs.getString("username"); userAuthority=rs.getString("authority"); %> <OPTION VALUE="<%= userID %>"><%= userName %></OPTION> <% } statement.close(); connection.close(); %> </SELECT> ○ 現在の年月を取得する ・ プルダウンメニューで年を選べるようにするために、メニューに表示する 最大年を maxYear で指定する。 ・ 日付を入れる器として calendar という名前で GregorianCalendar オブジ ェクトを作る。 ・ Date クラスから current という名前で現在日時を取得する。 ・ calendar に対して現在日時を set メソッドでセットする。 今年が何年か調べて thisyear に代入 int maxYear=2010;//最大で表示できる年 //現在の日時を設定 // Calendar calendar = new GregorianCalendar(); Date current=new Date(); //calendar に現在の日時 current をセットする calendar.setTime(current); 2.displaySchedule.jsp ○スケジュールを表示する ・ 今日の日付の表示 ・ 誰のスケジュールかわかるようにユーザー名の表示 ・ カレンダーを「前月」、「翌月」に移動するためのボタンの表示 ・ いつのカレンダーを表示しているかわかるようにカレンダーの年月を表示 ・ 日付をクリックすると、新規追加画面へ ・ スケジュール名をクリックすると編集画面へ ・ TOP画面へのリンクを表示 ○変数・文字列の宣言 int dispYear; int dispMonth; 表示年 //表示月 // 表示日 int dayOfWeek; //表示日の曜日 int tempYear; //年を表すテンポラリ変数 int tempMonth; //月を表すテンポラリ変数 int tempDay; //日を表すテンポラリ変数 Date tempDate; //日を表すテンポラリ変数 String tempStartTime; //開始時刻を表すテンポラリ変数 String tempEndTime; //終了時刻を表すテンポラリ変数 int tempDayOfWeek; //曜日を表すテンポラリ変数 String userID; //ユーザーID String userAuthority; //グループ番号 String userName; //ユーザーネーム String scheduleID; //スケジュール ID String title; //スケジュール内容 String place; //開催場所 String[] items=new String[32]; //各日のスケジュールを入れる変数 int dispDay; // ○スケジュール配列変数のクリア ・ for 文を使い、各日のスケジュール内容を String 型で保持しておく配列を このプログラムが呼ばれる度にクリアしておく。 for(int i=1;i<32;i++) { items[i]=""; } ○ 今日の日付の表示 ・ 先ほどの schedule.jsp と同じように GregorianCalendar クラスと Date ク ラスを使って今日の年月日を tempYear、tempMonth、tempDay に代入す る ・ 曜日を tempDayOfWeek に代入する 今日の日付の表示 out.println("本日は"); // %> <strong> <% Calendar calendar = new GregorianCalendar(); Date current=new Date(); calendar.setTime(current); tempYear=calendar.get(Calendar.YEAR); tempMonth=calendar.get(Calendar.MONTH)+1; tempDay=calendar.get(Calendar.DATE); tempDayOfWeek=calendar.get(Calendar.DAY_OF_WEEK); out.println(tempYear+" 年 "+tempMonth+" ("+dow[tempDayOfWeek-1]+")"); 月 "+tempDay+" 日 %> </strong> <% out.println(" です。<BR>"); ○ スケジュール表示のための情報を取得 ・ 誰の、何年何月のスケジュールを表示するのか、userID、year、month、 パラメータから取得する ・ この displaySchedule.jsp は前月と翌月に移動するボタンがあり、クリック す る と dispMonth を 1 つ 減 ら し た り 、 増 や し た り し て 再 び dispSchedule.jsp を呼び出す ・ dispMonth が0のとき前月を表示しようとすると dispMonth が-1にな り、dispMonth が 11 のときはに翌月を表示しようとすると 12 で呼ばれて しまう。そうならないために、dispMonth が-1(0月)になったときに は dispMonth を 11(12 月)にするとともに dispMonth が 12 になったと きには逆に dispMonth を 0(1月)にして年を 1 つ進める // スケジュール表示の対象者をフォームから取得 userID=request.getParameter("userID"); // 表示するカレンダー設定 希望表示年 dispMonth=Integer.parseInt(request.getParameter("month"));// 希望表示月取得、範 囲内かどうかチェック if(dispMonth<0) //1 月より前に行ったら 12 月にして 1 年減らす dispYear=Integer.parseInt(request.getParameter("year"));// { dispMonth=11; dispYear-=1; } if(dispMonth>11) //12 月より先に行ったら 1 月にして 1 年増やす { dispMonth=0; dispYear+=1; } 希望表示年をセット calendar.set(Calendar.MONTH,dispMonth);//希望表示月をセット //表示するスケジュールの期間設定(今月 1 ヶ月分) calendar.set(Calendar.YEAR,dispYear);// String topDayOfMonth=dispYear+"/"+(dispMonth+1)+"/01"; String lastDayOfMonth=dispYear+"/"+(dispMonth+1)+"/"+daysOfMonth[dispMonth]; ○ スケジュール内容情報をスケジュールデータベースから抽出し、配列に格 納 ・ スケジュールデータベースに接続 ・ スケジュールを item という配列に入れる ・ 文字型でデータベースを読むなら getString メソッドだが、日付時間型の データを読む場合には getDate メソッド。これで読んだデータは Date 型 になる。ここから年、月、日のこの値を取得するには少し処理が必要であ る。前に用意してある Calendar 型変数である calendar に Date 変数 tempDate をセットして calendar をスケジュールの日時にする。何日であ るか知りたいので get(Calendar.DATE)を使う。これにより int 型変数 tempDay に日付が入る。 ・ 開始時刻フィールド startTime と終了時刻フィールド endTime は getTime で読み込むが、これを文字型に変換して substring(0,5)メソッドを使用し て先頭である 0 文字目から 5 文字分だけを切り出す。getTime では 14:30:00 といったように時:分:秒のデータが得られるが、スケジュールの表示で は秒までは要らないので先頭から 5 文字分だけにしている。 ・ if 文は item に既にスケジュールがあるかどうかを調べて処理を分けている。 これは、その日のスケジュールが 2 つあるなら1行にしないで改行して表 示するためである。既にスケジュールが入っているなら<BR>で改行を入れ る。 ・ データベースからの読み込みが終了したらデータソースを close にする。 ・ この段階ではまだスケジュールには表示されない。 ・ スケジュールを追加する時には<A>タグを使用し、後で編集画面にリンク するようにする。このとき編集を示す mode=2 とスケジュールの ID であ る scheduleID をパラメータとして渡す。 // スケジュールデータベース設定 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection connection=DriverManager.getConnection("jdbc:odbc:schedule","",""); Statement statement=connection.createStatement(); String qStr="SELECT * FROM table1 WHERE shainID="+userID+" AND day>=#"+topDayOfMonth+"# AND day<=#"+lastDayOfMonth+"#"; ResultSet rs=statement.executeQuery(qStr); // 検索したスケジュールを配列 items に格納する while(rs.next()) スケジュール ID 取得 title=s2u(rs.getString("title"));//スケジュール取得、コード変換 place=s2u(rs.getString("place"));//場所取得、コード変換 tempDate=rs.getDate("day");//日付を Date オブジェクトで取得 { scheduleID=rs.getString("scheduleID");// calendar.setTime(tempDate); 日にち要素の抽出 tempDay=calendar.get(Calendar.DATE);// 時刻取得 刻取得 tempStartTime=(rs.getTime("startTime")).toString().substring(0,5);// tempEndTime=(rs.getTime("endTime")).toString().substring(0,5);// 開始 開始時 各日のスケジュールを書き込んでいく // if(items[tempDay].length()!=0) { // その日に既にスケジュールがある場合は<BR>入れて追記 items[tempDay]=items[tempDay]+"<BR><A HREF='editSchedule.jsp?mode=2"+"&userID="+userID+"&scheduleID="+scheduleI D+"'>["+tempStartTime+"-"+tempEndTime+"]"+title+"("+place+")</A>"; }else { // その日の初めてのスケジュールの場合はそのまま代入 items[tempDay]="<A HREF='editSchedule.jsp?mode=2"+"&userID="+userID+"&scheduleID="+scheduleI D+"'>["+tempStartTime+"-"+tempEndTime+"]"+title+"("+place+")</A>"; } } statement.close(); connection.close(); ○スケジュールの表示(「前月」・「翌月」ボタンの表示) ・ FORM の ACTION 属性でこの displaySchedule.jsp を指定する。つまり、 自分自身で受け取って処理をする。displaySchedule.jsp は本来 shedule.jsp から呼ばれることになっているので、このフォームから呼ぶ場合にもそれ と同じ情報を渡す必要がある。ただし、月の指定 dispMonth は1を引いた り、足したりして渡している。これらのパラメータは全て表示する必要な いので全て hidden にしてある。 <TABLE ALIGN="center"> <TR><TD> 前月移動ボタン--> <!-- <FORM ACTION="displaySchedule.jsp" METHOD="post"> <INPUT TYPE="hidden" NAME="userID" VALUE="<%= userID %>"> <INPUT TYPE="hidden" NAME="year" VALUE="<%= dispYear %>"> <INPUT TYPE="hidden" NAME="month" VALUE="<%= dispMonth-1 %>"> < 前月"> <INPUT TYPE="submit" VALUE=" </FORM> </TD><TD> 翌月移動ボタン--> <!-- <FORM ACTION="displaySchedule.jsp" METHOD="post"> <INPUT TYPE="hidden" NAME="userID" VALUE="<%= userID %>"> <INPUT TYPE="hidden" NAME="year" VALUE="<%= dispYear %>"> <INPUT TYPE="hidden" NAME="month" VALUE="<%= dispMonth+1 %>"> 翌月 >"> <INPUT TYPE="submit" VALUE=" </FORM> </TD></TR> </TABLE> ○スケジュールの表示(カレンダー表を作成して表示する) ・表の枠を作る <TABLE BORDER=15 WIDTH="720" BORDER="2"> <TR> <% // スケジュールカレンダーをテーブルを使って書く // 先頭行に曜日を入れる for(int i=0;i<7;i++) { out.println("<TD WIDTH='100'>"+dow[i]+"</TD>"); } %> </TR> ・ 1日が何曜日か調べる ・ 変数 calendar はデータベースの検索結果を item 配列にセットするときに 使用しているのでスケジュールがあった場合にはその月の最後のスケジュ ールがある日になっているはずである。しかし、年月情報は表示希望のま まになっているので問題はない。日付だけを1日にセットし、曜日、年、 月をそれぞれ取得する。 <% // 今月の最初の日にして、曜日を調べる calendar.set(Calendar.DATE,1); tempDayOfWeek=calendar.get(Calendar.DAY_OF_WEEK); tempMonth=calendar.get(Calendar.MONTH); tempYear=calendar.get(Calendar.YEAR); ・ 曜日のデータは1から7までの整数で返される ・ 例えば、もし 1 日が水曜だったら日曜日から火曜日まで空白のセルを作ら なければいけない。そのための空白を作成する。(<TD>タグの中身が空) // 月初めが日曜日以外なら空白を挿入 if(tempDayOfWeek>1) { out.println("<TR>"); for(int i=1;i<tempDayOfWeek;i++) { out.println("<TD WIDTH='100'></TD>"); } } ・ スケジュールを表示していく ・ 日付をクリックしたらスケジュール追加(mode=1)、すでに登録されてい るスケジュール項目をクリックしたら編集(mode=2)できるようにする。そ のため、パラメータを伴った<A>タグを使用している ・ スケジュール追加の場合にはスケジュール追加を示す mode=1 でユーザー ID である userID、年月日の targetYear、targetMonth、targetDay を渡 す ・ 編集の場合には mode=2 という情報と scheduleID が埋め込まれるてすで に items 配列に入れてある ・ 土曜日になったら最後に</TR>タグを閉じて1行分を終わりにする //1 日づつ日を増やし、月が変わるまで続ける String tag1="<A HREF='editSchedule.jsp?mode=1"+"&userID="+userID+"&targetYear="+tempYear +"&targetMonth="+tempMonth+"&targetDay="; String tag2="&targetDayOfWeek="; String tag3="'>"; String tag4="</A>"; while(calendar.get(Calendar.MONTH)==dispMonth) 日にち { tempDay=calendar.get(Calendar.DATE); // tempDayOfWeek=calendar.get(Calendar.DAY_OF_WEEK); // if(tempDayOfWeek==1) // 日曜日なら<TR>を挿入 曜日 { out.println("<TR>"); } out.println("<TD WIDTH='100' VALIGN='top'>"); out.println(tag1+tempDay+tag2+tempDayOfWeek+tag3+tempDay+tag4); out.println("<BR>"); out.println(items[tempDay]); out.println("</TD>"); if(tempDayOfWeek==7) // 土曜日なら</TR>を挿入 { out.println("</TR>"); } calendar.add(Calendar.DATE,1); } ・第1週の空白挿入処理と同様に最終週で土曜日までの空白を挿入する // 最後が土曜日以外で終わった場合には空白を挿入 if(tempDayOfWeek<7) { for(int i=tempDayOfWeek+1;i<=7;i++) { out.println("<TD WIDTH='100'></TD>"); } out.println("</TR>"); } %> </TABLE> 3.editSchedule.jsp ・スケジュールの追加と編集は editSchedule.jsp で行う ・これは displayScheduele.jsp から呼ばれるプログラムである ・ここで追加、編集された後は自動的に再び displaySchedulel.jsp に戻って月 間スケジュールを表示する ○スケジュールの新規追加・編集・削除画面の表示 ・ 日付を選択するためのプルダウンメニューの表示 ・ 開始時刻・終了時刻を選択するためのプルダウンメニューの表示 ・ 用件、場所・行き先を入力するためのテキストボックスの表示 ・ スケジュールを新規追加・編集するのか、削除するのかを選択するための ラジオボタンの表示 ・ スケジュールが個人用かメンバー用かを選択するためのラジオボタンの表 示 ・ データベースへの更新処理をするための「OK」ボタンの表示 ○ mode を調べる ・ 1は新規スケジュールを追加するモード、2は既にあるスケジュールを編 集するモード。ただし、これらはデータベースの更新は行わずに表示する だけの働きである。 ・ 表示の後にユーザーから情報を入力してもらう。これらの入力を受けて採 集的にデータベースの更新するときにはモード11、12、111になる ・ 11はデータベースへ個人用スケジュールの追加を行うモード ・ 12はデータベースに登録されているスケジュール情報の変更 ・ 111はデータベースへメンバー用スケジュールの追加を行うモード ・ 他に13というモードがあり、この場合はスケジュール情報の削除である ・ (ここでは1か2かを判別して、swith 文で分別している) //mode の取得 1 は新規作成、2 は編集 mode=request.getParameter("mode"); if(Integer.parseInt(mode)==1 || Integer.parseInt(mode)==2) { //mode=1 or 2, スケジュールの新規追加または編集、入力フォームの表示のみ userID=request.getParameter("userID"); switch(Integer.parseInt(mode)) ○ mode=1 新規スケジュールの場合 ・ 年月日はわかっているので、それだけを必要な変数にセットする ・ ここでは情報を変数にセットするだけでデータベースへの書き換えは行わ ない ・ 画面への表示もまだ行われない スケジュール新規追加(入力の受け付けのみ) //月日、曜日の表示 case 1: // tempYear=Integer.parseInt(request.getParameter("targetYear")); tempMonth=Integer.parseInt(request.getParameter("targetMonth")); tempDay=Integer.parseInt(request.getParameter("targetDay")); tempDayOfWeek=Integer.parseInt(request.getParameter("targetDayOfWe ek")); break; ○ mode=2 編集の場合 ・ scheduleID がわかっているのでデータベースからその内容、日時を検索し て取得する ・ 画面への表示はまだ行われない スケジュール編集(入力の受け付けのみ) //検索すべきスケジュール ID の取得 case 2: // scheduleID=request.getParameter("scheduleID"); // データベース検索 Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection connection=DriverManager.getConnection("jdbc:odbc:schedule","",""); Statement statement=connection.createStatement(); qStr="SELECT * FROM table1 WHERE scheduleID="+scheduleID; ResultSet rs=statement.executeQuery(qStr); // 検索結果の分析 while(rs.next()) ・ データベース上では日付は 003/07/05 とうように年、月、日が組み合わさ っているので、これを Date 型の tempDate に格納した後、calendar にセ ットし、要素を一つずつ取り出している スケジュール取得、コード変換 place=s2u(rs.getString("place"));//場所取得、コード変換 tempDate=rs.getDate("day");//日付を Date オブジェクトで取得 { title=s2u(rs.getString("title"));// calendar = new GregorianCalendar(); calendar.setTime(tempDate); 年要素の抽出 tempMonth=calendar.get(Calendar.MONTH);//月要素の抽出 tempDay=calendar.get(Calendar.DATE);//日にち要素の抽出 tempYear=calendar.get(Calendar.YEAR);// 素の抽出 tempDayOfWeek=calendar.get(Calendar.DAY_OF_WEEK);// 曜日要 ・ 開始時刻と終了時刻を、「時」と「分」に分けて抽出する ・ 開始時刻は「startTime」を Date 型の tempDate にセットするそれを Calendar 型の calendar にセットする。そこから「時」と「分」をそれぞ れ抽出する ・ 終了時刻も開始時刻と同様の要領で「時」と「分」を抽出する ・ 時間の要素は12時間表示で返ってくるので24時間表示に変換している で取得 tempDate=rs.getTime("startTime");// 開始時刻を Date オブジェクト calendar.setTime(tempDate); 時要素の抽出 if(calendar.get(Calendar.AM_PM)==Calendar.PM)//24 時間表示に変 tempStartHour=calendar.get(Calendar.HOUR);// 換 { tempStartHour+=12; } 分要素の抽出 tempDate=rs.getTime("endTime");//終了時刻を Date オブジェクトで tempStartMinute=calendar.get(Calendar.MINUTE);// 取得 calendar.setTime(tempDate); 時要素の抽出 if(calendar.get(Calendar.AM_PM)==Calendar.PM)//24 時間表示に変 tempEndHour=calendar.get(Calendar.HOUR);// 換 { tempEndHour+=12; } tempEndMinute=calendar.get(Calendar.MINUTE);// } 分要素の抽出 statement.close(); connection.close(); default: break; ○ 日時、内容、場所の情報をフォームとして画面へ表示 ・ フォームで入力した情報は editSchedule.jsp 自分自身に送られる <FORM ACTION="editSchedule.jsp" METHOD="post"> 日付-- ・ 年をプルダウンメニューで表示 <SELECT NAME="year"> <% for(int i=2002;i<2010;i++) { out.println("<OPTION VALUE='"+i+"' "); if(i==tempYear) { out.println("SELECTED"); } out.println(">"+i); } %> </SELECT> 年 ・ 月をプルダウンメニューで表示 <SELECT NAME="month"> <% for(int i=0;i<12;i++) { out.println("<OPTION VALUE='"+i+"' "); if(i==tempMonth) { out.println("SELECTED"); } out.println(">"+(i+1)); } %> </SELECT> 月 ・ 日をプルダウンメニューで表示 <SELECT NAME="date"> <% for(int i=1;i<32;i++) { out.println("<OPTION VALUE='"+i+"' "); if(i==tempDay) { out.println("SELECTED"); } out.println(">"+i); } %> </SELECT> 日 ・ 開始時刻の「時」をプルダウンメニューで表示 <P> 開始時刻 <SELECT NAME="sHour"> <% for(int i=0;i<24;i++) { out.println("<OPTION VALUE='"+i+"' "); if(i==tempStartHour) { out.println("SELECTED"); } out.println(">"+i); } %> </SELECT> 時 ・ 開始時刻の「分」をプルダウンメニューで表示 <SELECT NAME="sMin"> <% for(int i=0;i<60;i+=5) { out.println("<OPTION VALUE='"+i+"' "); if(i==tempStartMinute) { out.println("SELECTED"); } out.println(">"+i); } %> </SELECT> 分 ・ 終了時刻の「時」をプルダウンメニューで表示 <P> 終了時刻 <SELECT NAME="eHour"> <% for(int i=0;i<24;i++) { out.println("<OPTION VALUE='"+i+"' "); if(i==tempEndHour) { out.println("SELECTED"); } out.println(">"+i); } %> </SELECT> 時 ・ 終了時刻の「分」をプルダウンメニューを表示 <SELECT NAME="eMin"> <% for(int i=0;i<60;i+=5) { out.println("<OPTION VALUE='"+i+"' "); if(i==tempEndMinute) { out.println("SELECTED"); } out.println(">"+i); } %> </SELECT> 分 ・用件を入力するための欄をテキストボックスで表示 <P> 用件 <BR> <INPUT TYPE="text" NAME="title" SIZE=80 VALUE="<%= title %>"> ・場所・行き先を入力するための欄をテキストボックスで表示 <P> 場所・行き先 <BR> <INPUT TYPE="text" NAME="place" SIZE=80 VALUE="<%= place %>"> <P> ・ ここまでは mode=1 または 2 できていたが、これから先はデータベース操 作になるので mode を 11 か 12 にする。そのために mode に 10 を加える ・ 削除するかどうかを示す deleteFlag がある。これは1なら削除、0なら編 集である。これが1の時は mode を 13 に後で変更する。 ・ 個人用スケジュールかメンバー用スケジュールかどうかを示す kyodo がる。 これは0なら個人用、1ならメンバー用である。これが1の時は mode に 100 を足して 111、112、113 のいずれかに後で変更する。 ・ ユーザーが入力が終わって「OK」ボタンをクリックすると再び自分自身 editSchedule.jsp が呼ばれる。その場合には mode が 11 または 12 で実行 される。 <% mode=""+(int)(Integer.parseInt(mode)+10);//mode は 12 でデータベース更新 の変更、新規は 11、編集 %> <P> 新規 <INPUT TYPE="radio" NAME="deleteFlag" VALUE="0" CHECKED> 追加または編集 削除<BR> <INPUT TYPE="radio" NAME="deleteFlag" VALUE="1" > <% // 共同用スケジュールを選択するためのラジオボタン %> 個人用ス <INPUT TYPE="radio" NAME="kyodo" VALUE="0" CHECKED> ケジュール ール <INPUT TYPE="radio" NAME="kyodo" VALUE="1" > メンバー用スケジュ <INPUT TYPE="hidden" NAME="mode" VALUE="<%= mode %>" > <INPUT TYPE="hidden" NAME="scheduleID" VALUE="<%= scheduleID %>" > <INPUT TYPE="hidden" NAME="userID" VALUE="<%= userID %>" > <P> OK"> <INPUT TYPE="submit" VALUE=" </FORM> ○ mode=11 個人用スケジュール新規追加実行(データベースの更新) ・ SQL文で INSERT 命令を使用する ・ 必要な情報は既に変数にセットされているのでそれをデータベースに更新 する ・ ()の中が新規追加項目、()の中が新規追加項目のそれぞれの値 case 11: // 新規追加実行 qStr="INSERT INTO table1 (shainID,title,place,day,startTime,endTime) VALUES("+userID+",'"+title+"','"+place+"',"+tempDateString+","+startTime+","+e ndTime+")"; statement.executeUpdate(qStr); break; ○ mode=2 スケジュール編集(デーベースの更新) ・ SQL文で UPDATE 命令を使用する ・ WHERE 句を付けて対応する scheduleID のところのデータに対して内容 更新を実行する 編集実行 //変更すべきスケジュール ID の取得 case 12: // scheduleID=request.getParameter("scheduleID"); qStr="UPDATE table1 SET shainID="+userID+",title='"+title+"',place='"+place+"',day="+tempDateString+",s tartTime="+startTime+",endTime="+endTime+" scheduleID="+scheduleID; statement.executeUpdate(qStr); break; ○ mode=13 スケジュール削除(データベースの情報を削除) ・ 対応する scheduleID のデータを DELETE 文で削除する 削除実行 //変更すべきスケジュール ID の取得 case 13: // scheduleID=request.getParameter("scheduleID"); qStr="DELETE FROM table1 WHERE scheduleID="+scheduleID; statement.executeUpdate(qStr); break; WHERE ○ mode=111 メンバー用スケジュール新規追加(データベースへの情報の更 新)とメールによる自動連絡 ・ 必要な情報は既に変数にセットされているのでそれをデータベースに更新 する。 ・ ただし、今回はメンバー用スケジュールなので、for 文で全てのユーザー名 でデータベースへの書き換えを行っている ・ shainID がユーザーデータベース上でのユーザー名を表す ID に対応して いる。 メンバー用スケジュール新規追加 case 111:// for(int i=1;i<17;i++) { qStr="INSERT INTO table1 (shainID,title,place,day,startTime,endTime) VALUES("+i+",'"+title+"','"+place+"',"+tempDateString+","+startTime+","+endTime +")"; statement.executeUpdate(qStr); } ○メールの自動送信 ・ メンバー用スケジュールが更新されたことを自動的にメールを送信して連 絡する ・page ディレクティブで次のようなパッケージをインポートする <%@ page import="javax.mail.*" %> <%@ page import="javax.mail.internet.*" %> ・アドレスや SMTP サーバーを設定する //アドレスなどの設定 //***の部分は自分のメール環境に合わせて設定する String to="[email protected]"; //***宛先 String subject="JSP からのメール"; //***題名 String from="[email protected]"; //***送信元 String personal="JSP 自動送信"; //***送信元(受信側メーラーで表示される文字) String cc=null; //***CC あて先 String bcc=null; //***BCC あて先 String smtphost="mail.edu.i.hosei.ac.jp"; ここは自由 String protocol="smtp"; //メールプロトコル //SMTP String mailer="JSP Java mailer"; // サーバー ・ Properties オブジェクトを取得して SMTP ホストを設定し、Session オブ ジェクトを取得する ・ Session からメッセージを作成する ・ これでメールを書く準備が出来上がる ・ SMTP サーバーの ID やパスワードは不要 Properties pros = System.getProperties();//SMTP pros.put("mail.smtp.host", smtphost); //Session ホストの設定 オブジェクトの取得 Session s = Session.getDefaultInstance(pros, null); // メッセージの取得 MimeMessage msg = new MimeMessage(s); ・ personal という変数を ShiftJIS で読めるようにコード変換しておく ・ personal は相手のメーラーでメール一覧を見たときに送信先の欄に表示さ れる名前 // 宛先 TO,CC,BCC の設定 personal=new String(personal.getBytes("iso-2022-jp"),"JISAutoDetect"); ・msg.setFrom メソッドで送信元メールアドレスと personal の両方の設定をす る。ここで personal 省略してパラメータ1つでコールすることも可能。 msg.setFrom(new InternetAddress(from,personal)); ・ msg.addRecipient メソッドで受信者アドレスを追加する ・ 次に続く CC や BCC アドレスの設定でも同じメソッドを使っているが、 msg.addRecipient(Message.RecipientType.TO,new InternetAddress(to)); if (cc != null) msg.addRecipient(Message.RecipientType.CC,new InternetAddress(cc)); if (bcc != null) msg.addRecipient(Message.RecipientType.BCC,new InternetAddress(bcc)); ・ ・ SUBJECT の設定 日本語も使えるようにコード変換する subject=new String(subject.getBytes("iso-2022-jp"),"JISAutoDetect"); msg.setSubject(subject); ・ 本文の設定 ・ 日本語コード変換して、msg.setText(sendMsg)でセットする。 String sendMsg=" スケジュール帳にメンバー用スケジュールが更新されました!"; sendMsg=new String(sendMsg.getBytes("iso-2022-jp"),"JISAutoDetect"); msg.setText(sendMsg); // メーラー設定 msg.setHeader("X-Mailer",mailer); // 送信時刻の設定 msg.setSentDate(new Date()); // 送信 Transport.send(msg); break; ○ displaySchedule.jsp に戻る ・ 一連のデータベース操作が終わったら変更結果を表示するために月間スケ ジュールの表示 displaySchedule.jsp にフォワードする ・ フォワードするときは、displaySchedule.jsp に必要なパラメータを渡さな ければいけない <jsp:forward page="displaySchedule.jsp?userID=<%= userID %>&year=<%= tempYear %>&month=<%= tempMonth %>" /> 4.userHenkou1.jsp(ユーザー認証画面の表示) ・ ・ ・ ・ ・ ユーザー名を入力するためのテキストボックスの表示 パスワードを入力するためのテキストボックスの表示 ユーザー情報変更画面へうつるための「OK」ボタンの表示 TOP 画面へ戻るための「TOP へ戻る」ボタンの表示 フォームで入力されたユーザー名とパスワードの情報を「OK」ボタンがク リックされたときに userHenkou.jsp におくる 5.userHenkou.jsp(ユーザー認証処理) ○userHenkou1.jsp からユーザー名「user」、パスワード「pw」を受け取って ユーザーデータベースと照合する ・userHenkou1.jsp から情報を取得する // フォームからユーザー名取得 String user=request.getParameter("user"); // フォームからパスワード取得 String pw=request.getParameter("pw"); ・ ユーザー名が空白で post された場合には例外 Exeption を表示する ・ 表示されるメッセージが日本語になるようにコード変換をする 入力情報が不足していないかチェック //エラー表示を日本語にする // if(user.equals("")) ユーザー名がありません。"; { String errorMsg=" errorMsg=new String(errorMsg.getBytes("8859_1"),"SJIS"); ユーザー名がありません。"); throw new Exception(" } ・ ユーザーデータベースに接続した後、データベースに登録されているパス ワードを取得する必要がある ・ ここでは先ほど userHenkou1.jsp で入力したユーザー名とデータベースに 登録されているユーザー名が一致するものを検索し、一致したものの情報 を全て抽出している。本来はユーザー名とパスワードの2つだけを抽出す れば照合はできるのだが、この後のユーザー情報変更画面の表示でその他 の情報も使用するのでここでそのユーザーの全ての情報を抽出している。 //SQL 文の設定と検索実行 String qStr="SELECT password,idnumber,department,mail,extension FROM table1 WHERE username='"+user+"'"; ResultSet rs=statement.executeQuery(qStr); // マッチした最初のアイテム(マッチするものだけが1つだけと想定) rs.next(); ・ パスワードの確認 ・ if 文を使用し、フォームで入力したパスワードとデータベースに格納され ているパスワードが一致したらそれ以降の処理に進めるようにする ・ パスワードが違った場合はエラー文を表示する // パスワードの確認 String realPassword=rs.getString("password"); if(pw.equals(realPassword)) ( else { 一部省略) パスワードが違います。"; String errorMsg=" errorMsg=new String(errorMsg.getBytes("8859_1"),"SJIS"); パスワードが違います。"); throw new Exception(" } ○ ・ ・ ・ ・ ・ ・ ・ ユーザー情報変更画面の表示 ユーザー名の表示 学籍番号の表示 パスワードを変更するためのテキストボックスの表示 所属ゼミを変更するためのテキストボックスの表示 メールアドレスを変更するためのテキストボックスの表示 電話番号を変更するためのテキストボックスの表示 変更するために入力したものをキャンセルするための「キャンセルボタン」 の表示 ・ 変更するために入力したものを変更するための「OK」ボタンの表示 ・ TOP 画面へ戻るための「TOP へ戻る」ボタンの表示 ・ 個人情報が表示されるが、ユーザー名と学籍番号だけは変更できない ・ フォームの post 先は userHenkouShori.jsp になっている。ここでユーザ ーデータベースへの更新をおこなう 6.error.jsp(エラー表示) ・下の例にあるようにユーザー名や、パスワードにエラーがあった時に呼ばれ る 7.userHenkouShori.jsp(ユーザー情報変更処理) ・ユーザー情報をユーザーデータベースへ更新する ・データベースへの更新が終了したことを画面へ表示する ・ユーザー情報が更新されたことを確認するために、ユーザー情報変更画面 (userHenkou.jsp)へ戻るための「もどる」ボタンの表示 ・TOP 画面へ戻るための「TOP へ戻る」ボタンの表示 ○ UPDATE 文で SET 句と WHERE 句を使用してデータベースへの更新 // SQL文の設定と検索条件 String qStr="UPDATE table1 SET password='"+password+"' ,department='"+department+"' ,mail='"+mail+"',extension ='"+extension+"' WHERE username='"+user+"' "; statement.executeUpdate(qStr); 8.sercher.jsp(検索画面の表示) ・誰のスケジュールを表示するか選択するため、ユーザー名の一覧をプルダウ ンメニューで表示 ・ 検索するスケジュールのキーワードを入力するためのテキストボックスを 表示 ・ 検索結果を表示する serchSchedule.jsp へ移動するための「検索」ボタン の表示 ・ TOP 画面へ戻るための「TOP へ戻る」ボタンの表示 ・ ユーザー名を一覧表示する方法は、基本的には schedule.jsp と同じような つくりである ・ 今回は期間の限定は行わないので年月の指定はしない ・ フォームで取得したユーザー名と検索するスケジュールのキーワードを serchSchedule.jsp におくる 9.serchSchedule.jsp(検索処理・検索結果表示) ○画面への表示 ・今日の日付の表示 ・検索結果を表形式で表示 ・一つ前の検索条件入力画面へ戻るための「前のページにもどる」リンクを表 示 ○ ・ ・ ・ 検索処理を行う スケジュール表示の対象者と検索する言葉をフォームから取得する SELECT 文で検索を行う まづ、ユーザー名で検索をかけ、その後、その中から targetword を含むも のをさらに検索する。このように二つ以上のものを併用する場合に AND 句を使用する ・ targetword をワイルドカード文字の%で囲むことにより 0 個以上の任意の 文字を意味する ・ ORDER BY の後に day DESC と宣言することにより、日付が新しいもの から順番に並べられる String qStr="SELECT * FROM table1 WHERE shainID="+userID+" AND title LIKE '%"+targetword+"%' ORDER BY day DESC"; ResultSet rs=statement.executeQuery(qStr); 10.generalError.jsp(エラー表示) ・通常のプログラム処理の中でエラーが起きたときに呼び出され、画面にエラ ー内容を表示する 検討課題 ● セキュリティ強化 現段階ではユーザー認証がユーザー情報変更でしか行われないので、スケ ジュール表示のときと、スケジュール検索のときにも認証が行われる必要 がある。 ● ユーザー登録のオンライン化 ユーザーを登録するときに毎回 Access にデータを入力するのは手間がか かるのでこれをオンラインで登録できるようにする必要がある。 ● メール機能の改良 現在のメールの自動送信では新たにメンバー用スケジュールが更新された ことを連絡するのみだが、このメールにその更新されたスケジュールの内 容も表示されるようにしたい。 ● レイアウトの改良 見やすい、使いやすい、親しみやすいホームページにするために、ホーム ページをもっと改良していきたい。 参考文献 ・JSP&サーブレット~実用サンプル集~
© Copyright 2024 Paperzz