■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 2007年10月14日 楽しいJava講座 - 初心者から達人へのパスポート vol.074 セルゲイ・ランダウ バックナンバー: http://www.flsi.co.jp/Java_text/ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ [このメールマガジンは、画面を最大化して見てください。] ======================================================== ◆ 01.Tomcatのアプリケーション開発 ======================================================== 前回は、日本語(文字コードとしてShift_JISを使う場合)の文字 を表示するためのサーブレットの注意点についてお話しました。 しかし、今はグローバルな時代といわれていますし、今後は、 日本語以外にもさまざまな言語の文字を混在させるような国際的 なWebページを表示したい場面(例えば、同じページに韓国語(ハン グル文字)と日本語と中国語(簡体字)を同時に表示したい場合など) も増えてくるかもしれません。 この場合はShift_JISの代わりにUnicodeの出番となります。 (Unicodeは、同じコード体系で複数の言語の文字を扱えるように した文字コードなのです。) というわけで、Unicodeを使って日本語の文字を表示するように、 TestServletを書き換えてみましょう。(他の言語の文字の混在に ついては後述します。) TestServletを下記のように書き換えてみてください。 何が変わったかわかりますね。 -------------------------------------------------------- package jp.flsi.lecture.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>サーブレットのテストのページ</TITLE>"); out.println("</HEAD>"); out.println("<BODY bgcolor=\"#77ffff\" text=\"#fa5a00\">"); out.println("<H1>vol.074 テスト・ページ</H1>"); out.println("このページは、TestServletの出力です。"); out.println("</BODY>"); out.println("</HTML>"); } } -------------------------------------------------------- Unicodeにはいくつかのエンコーディング(encoding = 符号化: データを一定のルールに基づいて符号に変換すること)の方式があり、 現在一番よく使われているエンコーディングの方式はUTF-8です。 上記のソース・コードでも、UTF-8を使用しています。 (なお、混乱する人がいるので解説を加えますが、エンコーディングは 符号化という意味であり、文字を符号化すると符号(code = コード)に なります。(ここでいう符号は、コンピューターの内部では数値で表現され るものです。)この符号化された文字を文字コードと呼ぶことができますか ら、「エンコーディングはUTF-8を使います」というふうにエンコーディング を指定すれば文字コードが決まることになります。 そのため、エンコーディングと文字コードはしばしば同義で使われること があります。 しかし、文字コードという言葉は少々あいまいに使われています。 例えば、Unicodeなどの一つの文字体系(文字セット)自体を文字コード と呼ぶこともあり、文字コードという言葉だけではUTF-8などの特定の エンコーディングを表さないことがあります。 Unicodeでは、一つのエンコーディング方式だけでは都合が悪いことが あるため複数のエンコーディングが行われるようになったのです。 このように最近では、文字コードとエンコーディングが1対1に対応しなくなっ て来ています。 このため、混乱を避けるためには、エンコーディングという言葉を使ったほう がいいのです。) TestServletを上記のソース・コードのように編集したら、保管(コン パイル)し、サーブレットをテストしてみてください。 (サーブレットのテストの仕方を忘れた人はvol.072を復習してください。) 最近のWebブラウザーのほとんどは、UTF-8に対応していますから大丈夫 だと思いますが、もしうまく表示できないというWebブラウザーをお持ち の方がいましたら、このメールマガジンの下のほうに書いてある質問用の Webページにてご報告ください。 さて、ここでUnicodeに関係するお話で注意しなければならないことが ありますので、再度TestServletを編集してみましょう。 今度は、TestServletを下記のように書き換えて、テストしてみてくだ さい。 (注意:通常、Webブラウザーでは、以前見たのと同じWebページを開こう とするとキャッシュ(一時記憶)に残ったページを表示してしまうため、 変更された新しいページが見られません。この場合は、Webブラウザーの 更新ボタンを何度かクリックして最新のWebページを開くようにしてくだ さい。) -------------------------------------------------------- package jp.flsi.lecture.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter(); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>サーブレットのテストのページ</TITLE>"); out.println("</HEAD>"); out.println("<BODY bgcolor=\"#77ffff\" text=\"#fa5a00\">"); out.println("<H1>vol.074 テスト・ページ</H1>"); out.println("このページは、TestServletの出力です。"); out.println("@〜Bなどの特殊な文字が文字化けするのは?"); out.println("</BODY>"); out.println("</HTML>"); } } -------------------------------------------------------- どうですか。@〜Bの部分が文字化けしてしまいますね。 これがどういうことか、少し解説しておきましょう。 まず、Javaは内部コードとしてUnicodeを採用していることを以前 (vol.015で)お話しました。 これはJavaのソース・コードは、通常、そのコンピューターのネイ ティブな文字コードで書かれますが、ソース・コードをコンパイルして バイトコードに変換すると、文字や文字列のリテラルがUnicodeに変換 されるということを意味します。 たとえば、上記のソース・コードの例では、ダブルクウォーテーション (")で囲まれている文字列がUnicodeに変換されてバイトコードの中に 保管されることになります。 ところが、上記のソース・コードでは、 -------------------------------------------------------- response.setContentType("text/html; charset=Shift_JIS"); -------------------------------------------------------- という指定がありますから、Tomcatはこれらの文字列をUnicodeから Shift_JISに変換してWebブラウザーに返します。 ところが、(文字コード自体は標準化されていても)文字コードの 変換(一つの文字コードから別の文字コードへの変換)はきちんと 標準化されておらず、問題が生じることがあるのです。 つまり、上記のテストで文字化けしたように、特殊な文字の場合、 適切に変換されない文字がいくつかあるのです。 では、今度はTestServletを再度、次のように書き換えてテストして みてください。 -------------------------------------------------------- package jp.flsi.lecture.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>サーブレットのテストのページ</TITLE>"); out.println("</HEAD>"); out.println("<BODY bgcolor=\"#77ffff\" text=\"#fa5a00\">"); out.println("<H1>vol.074 テスト・ページ</H1>"); out.println("このページは、TestServletの出力です。"); out.println("@〜Bなどの特殊な文字が文字化けするのは?"); out.println("</BODY>"); out.println("</HTML>"); } } -------------------------------------------------------- これは、たんにShift_JISをUTF-8に書き換えただけですね。 これなら、Unicodeの文字列がUnicodeのまま表示されることになりますね。 テストしてみると、文字化けが起こらないことがわかります。 この文字化けの問題については、また後ほど再度詳しくお話いたします。 では、続いて、doPost()メソッドを使ったサーブレットのお話を しましょう。 今度は、POST方式を使うわけですから、HTML(HTML自体は後ほど 詳しく説明します)のFORMタグというものを使って、サーブレットを 呼ぶ出すようにHTMLのファイルを作成しておきます。 (1) Eclipseのパッケージ・エクスプローラーでJStudy2を右クリックし、 「新規」→「ファイル」を選択します。 (2) 「ファイル名」にtestform01.htmlと入力し、「OK」ボタンをクリック しましょう。 (3) パッケージ・エクスプローラーの中にtestform01.htmlができました ら、それを右クリックし、「アプリケーションから開く」→ 「テキスト・エディター」を選択します。 testform01.htmlのエディターが開きましたら、下記のようなコードを 入力して保管(Ctrl + S)しましょう。 -------------------------------------------------------- <HTML> <HEAD> <TITLE>サーブレットのdoPostのテストのページ</TITLE> </HEAD> <BODY bgcolor="#77ffff" text="#fa5a00"> <H1>vol.074 doPostのテスト・ページ</H1> <FORM action="http://localhost:8080/JStudy2/servlet/test2" method="POST"> 生年月日をYYYYMMDDの形式で入力してください。 <BR> <INPUT TYPE="text" NAME="dayOfBirth" VALUE="" SIZE=10> <BR> <BR> <INPUT TYPE="submit" NAME="sumit" VALUE="送信"> </FORM> </BODY> </HTML> -------------------------------------------------------- 続いて、サーブレットを作りましょう。 TestServletと同じパッケージ内に下記のソース・コードのような サーブレットを作ってみてください。サーブレットのクラス名は TestServlet2です。 作業を簡単に済ませるためにコピー&ペーストの機能を使ってみ ましょう。 (1) パッケージ・エクスプローラーの中のTestServlet(これが コピー元)を右クリック→「コピー」を選択します。 (2) パッケージ・エクスプローラーの中のjp.flsi.lecture.servlet (これがペースト(貼り付け)先)を右クリック→「貼り付け」を 選択します。 (3) 「名前の競合」ウインドウが表示されたら、「CopyOfTestServlet」 を「TestServlet2」に書き換えて「OK」ボタンをクリックします。 では、TestServlet2のエディターを開いて、下記のようにソース・ コードを編集しましょう。 -------------------------------------------------------- package jp.flsi.lecture.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet2 extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html; charset=Shift_JIS"); PrintWriter out = response.getWriter(); String dob = request.getParameter("dayOfBirth"); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>サーブレットのdoPostのテストの応答ページ</TITLE>"); out.println("</HEAD>"); out.println("<BODY bgcolor=\"#77ffff\" text=\"#fa5a00\">"); out.println("<H1>vol.074 doPostのテスト・応答ページ</H1>"); out.println("あなたの生年月日は" + dob.substring(0, 4) + "年" + dob.substring(4, 6) + "月" + dob.substring(6, 8) + "日です。"); out.println("</BODY>"); out.println("</HTML>"); out.close(); } } -------------------------------------------------------- ソース・コードの解説は次回行います。 このTestServlet2は新しいサーブレットですから、web.xmlに登録しておく 必要があります。 そこで、web.xmlを下記のように編集してください。(web.xmlの内容に ついても、後ほど説明いたします。) -------------------------------------------------------- <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>TestServlet</servlet-name> <servlet-class>jp.flsi.lecture.servlet.TestServlet</servlet-class> </servlet> <servlet> <servlet-name>TestServlet2</servlet-name> <servlet-class>jp.flsi.lecture.servlet.TestServlet2</servlet-class> </servlet> <servlet-mapping> <servlet-name>TestServlet</servlet-name> <url-pattern>/servlet/test</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TestServlet2</servlet-name> <url-pattern>/servlet/test2</url-pattern> </servlet-mapping> </web-app> -------------------------------------------------------- 編集して保管したら、Tomcatを再起動しましょう。 そして、Webブラウザーで以下のURLを開いてください。 http://localhost:8080/JStudy2/testform01.html このWebページに生年月日をYYYYMMDDの形式で入力してみましょう。 たとえば、1981年2月3日生まれの人であれば、 19810203 と入力します。 そして「送信」ボタンをクリックします。 そうすると、「あなたの生年月日は1981年02月03日です。」と答える Webページが返って来ますね。 今回はここまでにします。 何か、わからないところがありましたら、下記のWebページまで質問を お寄せください。 (続く) ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ★ホームページ: http://www.flsi.co.jp/Java_text/ ★このメールマガジンは 「まぐまぐ(http://www.mag2.com)」 を利用して発行しています。 ★バックナンバーは http://www.flsi.co.jp/Java_text/ にあります。 ★このメールマガジンの登録/解除は下記Webページでできます。 http://www.mag2.com/m/0000193915.html ★このメールマガジンへの質問は下記Webページにて受け付けて います。わからない所がありましたら、どしどしと質問をお寄 せください。 http://www.flsi.co.jp/Java_text/ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ Copyright (C) 2007 Future Lifestyle Inc. 不許無断複製 |