このページでは,Apache Tomcat 上で動く Java サーブレット・プログラムの見本を示すとともに,作成手順を図解で説明する.
【この Web ページの目次】
【補足説明】
下記の 2つのサーバは別物です. 2つを同時に動かすことはできません(ポートを奪い合うことができないので).一方を動かすときは,もう一方を止めることになる.
Eclipse では,Eclipse 内部の tomcat サーバが動き, Java サーブレットの動作テストなどに使う.
Eclipse とは無関係の tomcat サーバ(C:\tomcat55\bin\tomcat5w.exe 等で起動する Tomcat サーバのこと).当然, 公開 tomcat サーバが管理するディレクトリも Eclipse とは独立している.
なお,「Eclipse 内部の tomcat サーバ」を使えるようには, Eclipse で「新規サーバの定義」を行う必要がある.これは,1回行うだけで十分です.
C:\Program Files\Java\jdk1.6.0_11 のようなディレクトリがあれば,インストール済み.
前もって,Tomcat インストールディレクトリを調べておいてください.
「Eclipse を使用しての Java サーブレット・プログラム開発」の Web ページの記述に従って,下記の作業を終えていること.
このページでは,Eclipse のプロジェクト名を hoge と書く.
このページでは,Java パッケージ名を hoge.hoge.com と書く.
このページでは,Java サーブレットのクラス名を HelloWorld と書く.
エディタでクラス定義を行う.クラス定義は下記の通り.
※ パッケージ名を「hoge.hoge.com」と書いているので,適切に読み替えてください.
【プログラムの要点】
Web ブラウザが,所定の「リクエスト URL」を使って Web ページを読み込もうとすると,HelloWorld クラスの doGet() メソッドが呼び出される
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) を右クリック
ウインドウが開くので, 「ローカルホストの Tomcat v5.5 サーバ」が選択されていることを確認の後,「次へ (Next)」をクリック.
「終了」をクリック.
コンソール・ビューに表示される.
Eclipse の 組み込み Web ブラウザ (Internal Web ブラウザ)が開き,そこに, 名前、学籍番号、所属のフォームが開く。
Eclipse の組み込み Web ブラウザ内のアドレスバーの部分は,
http://localhost:8080/hoge/HelloWorld
のようになっていることを確認しておきます.(「hoge」の部分は,プロジェクト名に読み替える)
上記の「例1」では,フォームタグを含む HTML ドキュメントを doGet() メソッド内で,動的に生成していたが,今回の例では, doGet() メソッドは使わない. index.html (フォームタグを含む HTML ファイル)を使う.
form タグの action 属性に「HelloWorld」のように URL が指定されていることに注意. つまり, index.html (フォームタグを含む 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>
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) を右クリック
ウインドウが開くので, 「ローカルホストの Tomcat v5.5 サーバ」が選択されていることを確認の後,「次へ (Next)」をクリック.
「終了」をクリック.
コンソール・ビューに表示される.
Eclipse の 組み込み Web ブラウザ (Internal Web ブラウザ)が開き,そこに, 名前、学籍番号、所属のフォームが開く。
Eclipse の組み込み Web ブラウザ内のアドレスバーの部分は,
http://localhost:8080/hoge/HelloWorld
のようになっていることを確認しておきます.(「hoge」の部分は,プロジェクト名に読み替える)
Tomcat サーバが起動した状態で,Web ブラウザにおいて,リクエスト URL である「http://localhost:8080/hoge/HelloWorld」を読み込むと, HelloWorld の doGet() メソッドが実行される. doGet() メソッドは,1行掲示板への書き込みのための入力フォームを表示する.
すでに書き込み済みの記事がログファイルに記録されている場合は,表示を行う.
1行掲示板の入力フォームに書き込んだ後,「送信」ボタンをクリックすると,doPost メソッドが呼び出されます.
doPost() メソッドでは,入力フォームに書き込まれただ内容をログファイル C:\bbslog.log に記録するとともに, 画面に表示する. 表示された画面で「掲示板に戻る」をクリックすると,doGet () に戻る.
【使用上の注意】
ログファイル名を変更したいときは, 「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) を右クリック
ウインドウが開くので, 「ローカルホストの Tomcat v5.5 サーバ」が選択されていることを確認の後,「次へ (Next)」をクリック.
「終了」をクリック.
コンソール・ビューに表示される.
Eclipse の 組み込み Web ブラウザ (Internal Web ブラウザ)が開き,そこに, 1行掲示板の入力フォームが開く。
Eclipse の組み込み Web ブラウザ内のアドレスバーの部分は,
http://localhost:8080/hoge/HelloWorld
のようになっていることを確認しておきます.(「hoge」の部分は,プロジェクト名に読み替える)