Java サーブレット・プログラムの見本と Eclipse での作成手順
このページでは,Apache Tomcat 上で動く Java サーブレット・プログラムの見本を示すとともに,作成手順を図解で説明する.
【この Web ページの目次】
- 例1: doGet, doPost メソッドを使用したフォームプログラム
- 例2: index.html と doPost メソッドを使用したフォームプログラム
- 例3:doGet とdoPost を使った1行掲示板
【補足説明】
下記の 2つのサーバは別物です. 2つを同時に動かすことはできません(ポートを奪い合うことができないので).一方を動かすときは,もう一方を止めることになる.
- Eclipse 内部の tomcat サーバ:
Eclipse では,Eclipse 内部の tomcat サーバが動き, Java サーブレットの動作テストなどに使う.
- 公開 tomcat サーバ:
Eclipse とは無関係の tomcat サーバ(C:\tomcat55\bin\tomcat5w.exe 等で起動する Tomcat サーバのこと).当然, 公開 tomcat サーバが管理するディレクトリも Eclipse とは独立している.
なお,「Eclipse 内部の tomcat サーバ」を使えるようには, Eclipse で「新規サーバの定義」を行う必要がある.これは,1回行うだけで十分です.
必要となるソフトウェア
- Windows での Java JDK 18 (Java SE Development Kit 18) のインストールが済んでいること.
C:\Program Files\Java\jdk1.6.0_11 のようなディレクトリがあれば,インストール済み.
- Eclipse のWebページの記述に従って,Eclipse のインストールが終わっていること.
- 「Tomcat インストール」の Web ページの記述に従って,Tomcat のインストールが終わっていること.
- 「Eclipse 内部の tomcat サーバ」を使えるようにするために, 「Eclipse を使用しての Java サーブレット・プログラムの開発」の Web ページに記載 の「新規サーバの定義」を行っておくこと.
設定項目
前もって,Tomcat インストールディレクトリを調べておいてください.
事前の準備
「Eclipse を使用しての Java サーブレット・プログラム開発」の Web ページの記述に従って,下記の作業を終えていること.
- Eclipse で,動的 Web プロジェクトの作成
このページでは,Eclipse のプロジェクト名を hoge と書く.
- Java パッケージの作成」
このページでは,Java パッケージ名を hoge.hoge.com と書く.
- サーブレットの作成
このページでは,Java サーブレットのクラス名を HelloWorld と書く.
例1: doGet, doPost メソッドを使用したフォームプログラム
クラス HelloWorld の定義
エディタでクラス定義を行う.クラス定義は下記の通り.
* パッケージ名を「hoge.hoge.com」と書いているので,適切に読み替えてください.
【プログラムの要点】
- doGet() メソッド:
Web ブラウザが,所定の「リクエスト URL」を使って Web ページを読み込もうとすると,HelloWorld クラスの doGet() メソッドが呼び出される
- doPost() メソッド:
doGet() メソッドが動的に生成する HTML ドキュメントの中にフォーム (form) タグがある. その フォーム (form) タグのアクション (action) 属性には「HelloWorld」と書いている. これは,「送信」ボタンをクリックしたときの遷移先 URL が,「HelloWorld」になるという意味(これは,相対形式の URL になっている).
遷移先 URL である HelloWorld は,HelloWorld クラスにマッピングされている.(このマッピング定義は,Eclipse が自動で行う).従って, 「送信」ボタンをクリックすると,HelloWorld クラスの doPost() メソッドが呼び出されることになる.
package hoge.hoge.com; import java.io.*; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class for Servlet: HelloWorld * */ public class HelloWorld extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#HttpServlet() */ public HelloWorld() { super(); } /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html; charset=utf-8"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3.org/TR/html4/loose.dtd\">"); out.println("<html>"); out.println("<head>"); out.println("<meta http-equiv="Content-Type" content="text/html; charset=utf-8">"); out.println("<title>フォーム入力</title>"); out.println("</head>"); out.println("<body>"); out.println("<P>"); out.println("以下のフォームに情報を記載してください。"); out.println("</P>"); out.println("<FORM method=\"POST\" action=\"./HelloWorld\">"); out.println("<TABLE summary=\"form of NAME, ID and BELONGS\">"); out.println("<TR>"); out.println("<TD>名前</TD>"); out.println("<TD><div> : <input type=\"text\" name=\"NAME\"></div></TD>"); out.println("</TR>"); out.println("<TR>"); out.println("<TD>学籍番号</TD>"); out.println("<TD><div> : <input type=\"text\" name=\"ID\"></div></TD>"); out.println("</TR>"); out.println("<TR>"); out.println("<TD>所属</TD>"); out.println("<TD><div> : <input type=\"text\" name=\"BELONGS\"></div></TD>"); out.println("</TR>"); out.println("</TABLE>"); out.println("<INPUT type=\"submit\" value=\"送信\">"); out.println("<INPUT type=\"reset\" value=\"取消\">"); out.println("</FORM>"); out.println("</body>"); out.println("</html>"); out.close(); } /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=iso-2022-jp"); request.setCharacterEncoding("iso-2022-jp"); PrintWriter out = response.getWriter(); String name = request.getParameter("NAME"); String id = request.getParameter("ID"); String belongs = request.getParameter("BELONGS"); out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3.org/TR/html4/loose.dtd\">"); out.println("<html>"); out.println("<head>"); out.println("<meta http-equiv="Content-Type" content="text/html; charset=utf-8">"); out.println("<title>入力結果の確認</title>"); out.println("</head>"); out.println("<body>"); out.println("<P>"); out.println("以下の情報を受け取りました。"); out.println("</P>"); out.println("<TABLE summary=\"table of NAME, ID and BELONGS\" border=\"1\">"); out.println("<TR>"); out.println("<TD>名前</TD>"); out.println("<TD><FONT color=red>" + name + "</FONT></TD>"); out.println("</TR>"); out.println("<TR>"); out.println("<TD>学籍番号</TD>"); out.println("<TD><FONT color=red>" + id + "</FONT></TD>"); out.println("</TR>"); out.println("<TR>"); out.println("<TD>所属</TD>"); out.println("<TD><FONT color=red>" + belongs + "</FONT></TD>"); out.println("</TR>"); out.println("</TABLE>"); out.println("<P>"); out.println("情報を修正する場合は以下の戻るボタンを押してください。"); out.println("<FORM method=\"GET\" action=\"./HelloWorld\">"); out.println("<INPUT type=\"submit\" value=\"戻る\">"); out.println("</FORM>"); out.println("</P>"); out.println("</body>"); out.println("</html>"); out.close(); } }
実行
- 実行したいサーブレットのクラスを選び,右クリック
Eclipse のプロジェクト・エクスプローラで,実行したいクラス名.java (つまり HelloWorld.java) を右クリック
- 「実行 (Run As)」→「サーバーで実行 (Run on Server)」と操作
- サーバの選択
ウインドウが開くので, 「ローカルホストの Tomcat v5.5 サーバ」が選択されていることを確認の後,「次へ (Next)」をクリック.
- 次はデフォルトのままでよい
「終了」をクリック.
- Eclipse 内部の Tomcat サーバが起動することを確認
コンソール・ビューに表示される.
- 実行結果の確認
Eclipse の 組み込み Web ブラウザ (Internal Web ブラウザ)が開き,そこに, 名前、学籍番号、所属のフォームが開く。
Eclipse の組み込み Web ブラウザ内のアドレスバーの部分は,
http://localhost:8080/hoge/HelloWorld
のようになっていることを確認しておきます.(「hoge」の部分は,プロジェクト名に読み替える)
- 試しに,名前,学籍番号,所属を記入し,「送信ボタン」をクリックする.
- 送信の結果,違う画面に切り替わることを確認する.
例2: index.html と doPost メソッドを使用したフォームプログラム
- doGet() メソッド: 呼び出されることはない.
上記の「例1」では,フォームタグを含む HTML ドキュメントを doGet() メソッド内で,動的に生成していたが,今回の例では, doGet() メソッドは使わない. index.html (フォームタグを含む HTML ファイル)を使う.
- doPost() メソッド: index.html ページにおいて「送信」ボタンをクリックすると,HelloWorld クラスの doPost() メソッドが呼び出される
form タグの action 属性に「HelloWorld」のように URL が指定されていることに注意. つまり, index.html (フォームタグを含む HTML ファイル)からサーブレットを呼び出している.
- 実行手順は,上記の HelloWorld と類似
HTML ファイル index.html
- Eclipse の プロジェクト・エクスプローラで,「WebContent」を右クリック. 「新規」→「HTML」と操作する.
- ファイル名 index.html の指定
ファイル名として index.html の指定し,
「次へ」をクリック.
- HTML テンプレートの選択
デフォルトのままでよい。「終了」をクリック.
- index.html の編集
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd"> "https://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>フォーム入力</title> </head> <body> <P> 以下のフォームに情報を記載してください。 </P> <FORM method="POST" action="./HelloWorld"> <TABLE summary="form of NAME, ID and BELONGS"> <TR> <TD>名前</TD> <TD><div> : <input type="text" name="NAME"></div></TD> </TR> <TR> <TD>学籍番号</TD> <TD><div> : <input type="text" name="ID"></div></TD> </TR> <TR> <TD>所属</TD> <TD><div> : <input type="text" name="BELONGS"></div></TD> </TR> </TABLE> <INPUT type="submit" value="送信"> <INPUT type="reset" value="取消"> </FORM> </body> </html>
クラス HelloWorld の定義
package hoge.hoge.com; import java.io.*; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class for Servlet: HelloWorld * */ public class HelloWorld extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#HttpServlet() */ public HelloWorld() { super(); } /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub } /* (non-Java-doc) * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=iso-2022-jp"); request.setCharacterEncoding("iso-2022-jp"); PrintWriter out = response.getWriter(); String name = request.getParameter("NAME"); String id = request.getParameter("ID"); String belongs = request.getParameter("BELONGS"); out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3.org/TR/html4/loose.dtd\">"); out.println("<html>"); out.println("<head>"); out.println("<meta http-equiv="Content-Type" content="text/html; charset=utf-8">"); out.println("<title>入力結果の確認</title>"); out.println("</head>"); out.println("<body>"); out.println("<P>"); out.println("以下の情報を受け取りました。"); out.println("</P>"); out.println("<TABLE border=\"1\">"); out.println("<TR>"); out.println("<TD>名前</TD>"); out.println("<TD><FONT color=red>" + name + "</FONT></TD>"); out.println("</TR>"); out.println("<TR>"); out.println("<TD>学籍番号</TD>"); out.println("<TD><FONT color=red>" + id + "</FONT></TD>"); out.println("</TR>"); out.println("<TR>"); out.println("<TD>所属</TD>"); out.println("<TD><FONT color=red>" + belongs + "</FONT></TD>"); out.println("</TR>"); out.println("</TABLE>"); out.println("<P>"); out.println("情報を修正する場合は以下の戻るボタンを押してください。"); out.println("<FORM method=\"GET\" action=\"./HelloWorld\">"); out.println("<INPUT type=\"submit\" value=\"戻る\">"); out.println("</FORM>"); out.println("</P>"); out.println("</body>"); out.println("</html>"); out.close(); } }
実行
- 実行したいサーブレットのクラスを選び,右クリック
Eclipse のプロジェクト・エクスプローラで,実行したいクラス名.java (つまり HelloWorld.java) を右クリック
- 「実行 (Run As)」→「サーバーで実行 (Run on Server)」と操作
- サーバの選択
ウインドウが開くので, 「ローカルホストの Tomcat v5.5 サーバ」が選択されていることを確認の後,「次へ (Next)」をクリック.
- 次はデフォルトのままでよい
「終了」をクリック.
- Eclipse 内部の Tomcat サーバが起動することを確認
コンソール・ビューに表示される.
- 実行結果の確認
Eclipse の 組み込み Web ブラウザ (Internal Web ブラウザ)が開き,そこに, 名前、学籍番号、所属のフォームが開く。
Eclipse の組み込み Web ブラウザ内のアドレスバーの部分は,
http://localhost:8080/hoge/HelloWorld
のようになっていることを確認しておきます.(「hoge」の部分は,プロジェクト名に読み替える)
- 試しに,名前,学籍番号,所属を記入し,「送信ボタン」をクリックする.
- 送信の結果,違う画面に切り替わることを確認する.
例3:doGet とdoPost を使った1行掲示板
- doGetメソッド:
Tomcat サーバが起動した状態で,Web ブラウザにおいて,リクエスト URL である「http://localhost:8080/hoge/HelloWorld」を読み込むと, HelloWorld の doGet() メソッドが実行される. doGet() メソッドは,1行掲示板への書き込みのための入力フォームを表示する.
すでに書き込み済みの記事がログファイルに記録されている場合は,表示を行う.
- ラジオボタンで本文の表示色を変更できる.
- 入力されたメールアドレスは,掲示板において,名前欄にリンクとして表示される.
- 空白の欄があった場合、適当に補完されます。
- doPostメソッド:
1行掲示板の入力フォームに書き込んだ後,「送信」ボタンをクリックすると,doPost メソッドが呼び出されます.
doPost() メソッドでは,入力フォームに書き込まれただ内容をログファイル C:\bbslog.log に記録するとともに, 画面に表示する. 表示された画面で「掲示板に戻る」をクリックすると,doGet () に戻る.
クラス HelloWorld の定義
【使用上の注意】
ログファイル名を変更したいときは, 「private static String LOG_FILE_NAME= "C:\\bbslog.log";」の行を書き換える.
package hoge.hoge.com; import java.io.*; import java.util.*; import java.text.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { public HelloWorld() { super(); } // ログファイル名 private static String LOG_FILE_NAME= "C:\\bbslog.log"; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=iso-2022-jp"); PrintWriter out = response.getWriter(); request.setCharacterEncoding("Shift-JIS");//SJISで受け取る StringBuffer sb = new StringBuffer(); StringBuffer sb3 = new StringBuffer(); // ログから読み出し、HTMLタグをつける sb.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3.org/TR/html4/loose.dtd\">"); sb.append("<html>"); sb.append("<meta http-equiv=\"Content-Type\" Content=\"text/html;charset=iso-2022-jp\">"); sb.append("<head>"); sb.append("<title>一行掲示板</title>"); sb.append("</head>"); sb.append("<body>"); //フォーム欄 sb.append("<h1>"); sb.append("一行掲示板"); sb.append("</h1>"); sb.append("<form action=\"./HelloWorld\" method=\"post\">"); sb.append("<table>"); sb.append("<tr>"); sb.append("<td>名前</td><td><input type=\"text\" size=\"20\" value=\"\" name=\"name\"></td></tr>"); sb.append("<tr>"); sb.append("<td>Mail</td><td><input type=\"text\" size=\"40\" value=\"\" name=\"mail\"></td></tr>"); sb.append("<tr>"); sb.append("<td>タイトル</td><td><input type=\"text\" size=\"40\" value=\"\" name=\"title\"></td></tr>"); sb.append("<tr>"); sb.append("<td>本文</td><td><input type=\"text\" size=\"100\" value=\"\" name=\"text\"><td></tr>"); sb.append("<tr>"); sb.append("<td>本文色</td>"); sb.append("<td>"); sb.append("<input type=\"radio\" name=\"color\" value=\"black\" checked><font color=\"black\">黒</font>"); sb.append("<input type=\"radio\" name=\"color\" value=\"red\"><font color=\"red\">赤</font>"); sb.append("<input type=\"radio\" name=\"color\" value=\"blue\"><font color=\"blue\">青</font>"); sb.append("<input type=\"radio\" name=\"color\" value=\"green\"><font color=\"green\">緑</font>"); sb.append("</td>"); sb.append("</tr>"); sb.append("</table>"); sb.append("<input type=\"submit\" name=\"button1\" value=\"送信\">"); sb.append("</form>"); sb.append("<hr width=\"95%\">"); out.println(new String(sb)); //読み出し try{ String line; BufferedReader logres = new BufferedReader( new InputStreamReader( new FileInputStream(LOG_FILE_NAME),"JISAutoDetect") ); //ログから書き込みを1つずつ読み出していく while((line = logres.readLine())!=null){ //書き込みの内容は配列で管理(1レスにつき1行) StringTokenizer Res = new StringTokenizer(line,"%|%"); StringBuffer sb2 = new StringBuffer(); int itemNum = Res.countTokens(); String[] item2 = new String[itemNum]; for(int i=0;i<itemNum;i++){ item2[i] = Res.nextToken(); //区切り文字で区切られたアイテムを1つずつロード } //タイトル sb2.append("<p>"); sb2.append("<b><big>"); sb2.append(item2[3]); //タイトル sb2.append("</big></b>"); //名前+メールアドレス sb2.append(" 名前:"); if(!item2[2].equals("None")){ sb2.append("<a href=\"mailto:"); sb2.append(item2[2]); //メール sb2.append("\">"); sb2.append(item2[1]); //名前 sb2.append("</a>"); } else{ sb2.append(item2[1]); } //タイトルと日付 sb2.append(" 投稿日:"); sb2.append(item2[0]); //日付 sb2.append("<br>"); //本文 sb2.append("<font color=\""); sb2.append(item2[5]); //色 sb2.append("\"> "); sb2.append(item2[4]); //本文 sb2.append("</font>"); sb2.append("</p>"); out.println(new String(sb2)); } logres.close(); sb3.append("</body>"); sb3.append("</html>"); out.println(new String(sb3)); } catch(IOException e){ e.printStackTrace(); } } // doGetの送信を押すと呼び出される protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ response.setContentType("text/html;charset=iso-2022-jp"); request.setCharacterEncoding("iso-2022-jp"); PrintWriter out = response.getWriter(); StringBuffer NewRes = new StringBuffer(); //書き込みデータの取得 //日時取得の定義 SimpleDateFormat date1 =new SimpleDateFormat("yyyy'年'MM'月'dd'日' HH:mm:ss"); Date resDate = new Date(); //各アイテムの取得 String name = request.getParameter("name"); String mail = request.getParameter("mail"); String title = request.getParameter("title"); String color = request.getParameter("color"); String text = request.getParameter("text"); String time = date1.format(resDate).toString(); //欄が空白のときの処理 if(name.isEmpty() == true) name = "名無しさん"; if(mail.isEmpty() == true) mail = "None"; if(title.isEmpty() == true) title = "(No Title)"; if(text.isEmpty() == true) text = " "; //ログファイルに新しい書き込みの情報を追加 try{ BufferedWriter newres = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(LOG_FILE_NAME,true),"Shift-JIS") ); //区切り文字は%|% newres.write(time+"%|%"+name+"%|%"+mail+"%|%"+title+"%|%"+text+"%|%"+color); newres.newLine(); newres.close(); } catch(IOException e){ e.printStackTrace(); } //確認の表示 out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3.org/TR/html4/loose.dtd\">"); out.println("<html>"); out.println("<meta http-equiv=\"Content-Type\" Content=\"text/html;charset=iso-2022-jp\">"); out.println("<head>"); out.println("<title>入力確認</title>"); out.println("</head>"); out.println("<body>"); NewRes.append("<p>"); NewRes.append("<b><big>"); NewRes.append(title); NewRes.append("</big></b>"); NewRes.append(" 名前:"); NewRes.append(name); NewRes.append(" 投稿日:"); NewRes.append(time); NewRes.append("<br>"); NewRes.append("<font color=\""); NewRes.append(color); NewRes.append("\">"); NewRes.append(text); NewRes.append("</font></p>"); out.println(new String(NewRes)); out.println("<p>"); out.println("上記の結果を受け取りました"); out.println("</p>"); out.println("<form method=\"get\" action=\"./HelloWorld\">"); out.println("<input type=\"submit\" value=\"掲示板に戻る\">"); out.println("</forn>"); out.println("</body>"); out.println("</html>"); out.close(); } }
「C:\bbslog.log」というファイル名の,空のテキストファイルを作っておきます.
*実行時に「同期できない」というエラーが出た場合は、いったんbbslog.logを削除して、 Eclipse上で再度作成するとうまくいくようです。
実行
- 実行したいサーブレットのクラスを選び,右クリック
Eclipse のプロジェクト・エクスプローラで,実行したいクラス名.java (つまり HelloWorld.java) を右クリック
- 「実行 (Run As)」→「サーバーで実行 (Run on Server)」と操作
- サーバの選択
ウインドウが開くので, 「ローカルホストの Tomcat v5.5 サーバ」が選択されていることを確認の後,「次へ (Next)」をクリック.
- 次はデフォルトのままでよい
「終了」をクリック.
- Eclipse 内部の Tomcat サーバが起動することを確認
コンソール・ビューに表示される.
- 実行結果の確認
Eclipse の 組み込み Web ブラウザ (Internal Web ブラウザ)が開き,そこに, 1行掲示板の入力フォームが開く。
Eclipse の組み込み Web ブラウザ内のアドレスバーの部分は,
http://localhost:8080/hoge/HelloWorld
のようになっていることを確認しておきます.(「hoge」の部分は,プロジェクト名に読み替える)
- 試しに,1行掲示板に記入し,「送信ボタン」をクリックする.
- 送信の結果,違う画面に切り替わることを確認する.
- 「掲示板に戻る」をクリックすると,掲示板に戻ることを確認する.