広告

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2010年12月28日

    Java総合講座 - 初心者から達人へのパスポート
                  vol.213

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


========================================================
◆ 00.お知らせ(バックナンバーの閲覧に関して)
========================================================


-------------------------------------------------------
・現在、このメールマガジンは以下の2部構成になっています。
[1] 当初からのコース:vol.xxx(xxxは番号)が振られています。
   これは現在、中級レベルになっています。
[2] 2009年11月開講コース:xxx号(xxxは番号)が振られています。
   これは現在、初心者向けのレベルになっています。
・このメールマガジンは、画面を最大化して見てください。
小さな画面で見ていると、不適切な位置で行が切れてしまう
など、問題を起すことがあります。
・このメールマガジンに掲載されているソース・コード及び
文章は特に断らない限り、すべて筆者が著作権を所有してい
ます。また、これらのソース・コードは学習用のためだけに
提供しているものです。
-------------------------------------------------------


========================================================
◆ 01.Strutsのアプリケーション開発(プロジェクト:StrutsShop)
========================================================

今回は、以前(vol.186で)お約束していた国際化に対応したStrutsアプリ
ケーションの作り方についてお話します。



Strutsは、画面(Webページ)の表示に使われる(自然)言語を日本語・英語・
中国語などの複数の言語の間で簡単に切り替えられるようにするための仕組み
を提供しています。

こういう機能を国際化(internationalization)と呼び、略してi18n
(internationalizationはiとnの間に18文字が入っているのでi18nと略す)
と書き表すことがあります。

┌補足─────────────────────────┐
細かく言うと、国際化(i18n)は(自然)言語の違いだけでなく、
日付の表記、金額の表記(通貨の違い)など数値関連の違いにも
対処するものです。数値といえば、小数点が日本などのほとんど
の国ではドット(.)を使って表記されるのに対し、フランスでは
コンマ(,)が使われますが、こういった違いにも対処します。
なお、金額を他の国の通貨を使って換算するためにはその時点の
為替レートを使って計算する必要がありますが、こういった計算
は通常のプログラミングで対処する必要があります。
実はJava自体にもi18nの仕組みが提供されており、Strutsもそれ
を利用しているのですが、Java自体のi18nの仕組みについては
また別の回でまとめてお話します。
└───────────────────────────┘


国際化は、そのアプリケーションが国際的に使用されるような場合(たとえば
商品を海外にも宅配するような商売をしている場合など)にWebアプリケーション
に必要な機能であり、今後のグローバルな社会では益々重要になってくると考え
られます。

という訳で、これからStrutsの国際化(i18n)について解説していきましょう。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆


Strutsの国際化は、基本的には(自然)言語に依存する部分をプロパティー・ファイル
にして言語ごとにファイルを分けることによって行われます。

つまり、各Webページに表示される文字列(メッセージ)を抽出して、それらを
各(自然)言語に翻訳したものを各言語ごとに(たとえば英語版と日本語版と
中国語版というふうに)別々のプロパティー・ファイルに収納することによっ
て行われます。

具体的には、JSPファイルの中の各文字列の部分を次のようなコードに置き換えます。

<bean:message key="プロパティー・ファイルの中のキー" />

これはプロパティー・ファイルからメッセージを取り出すためのコードであり、
ここに指定したキーに対する値(メッセージ)はプロパティー・ファイルの中に
記述しておく必要があります。
(プロパティー・ファイルの代わりにクラス・ファイルから値(メッセージ)を
取り出すことも可能だが、このやり方はほとんど使われないので説明は割愛する。)

このとき、プロパティー・ファイルは各言語ごとに別々のファイルにして、
それらには次のようなファイル名を付けます。

     ベースの名前_言語コード.properties

このうち"ベースの名前"は自分で自由に決めることができますが、
言語コードはISOで定まっている世界標準(ISO 639)の2文字のコード
を指定しなければなりません。

この言語コードには例えば次のようなものがあります。

ja 日本語(Japaneseの略)
en 英語(Englishの略)
zh 中国語(Zhongwenの略)

なお、すべての言語コードを知りたい人は、

http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt

などを参照して下さい。

また、言語コードの拡張として

言語コード_国コード

という指定も可能で、この場合の国コードはISOで定まっている世界標準
(ISO 3166)の2文字のコードを指定することになります。

この国コードには例えば次のようなものがあります。

JP 日本(Japanの略)
US 米国(United Statesの略)
GB 英国(Great Britainの略)
CN 中国語(Chinaの略)

例えば、同じ英語でもアメリカの英語とイギリスの英語には若干違いがありますが、
これらを区別して別々のプロパティー・ファイルに収納するためには、それぞれ

en_US
en_GB

と表記してファイル名に指定することになります。

なお、すべての国コードを知りたい人は

http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html

などを参照して下さい。


プロパティー・ファイルのベースの名前はstruts-config.xmlファイルの中で、

  <message-resources parameter="ベースの名前"/>

というように指定しておく必要がありますが、StrutsShopプロジェクトでは既に

  <message-resources parameter="MessageResources"/>

という行でMessageResourcesというベースの名前が指定されていますので、
このファイルをそのまま使用することにしましょう。



アプリケーションの実行時には、Strutsが自動的に適切な言語のプロパティー・
ファイルにアクセスしてくれるのですが、適切な言語のプロパティー・ファイル
が見つからない場合はデフォルトのプロパティー・ファイル(ファイル名に
言語コードが指定されていないプロパティー・ファイル)、すなわち

     ベースの名前.properties

というようなファイル名のプロパティー・ファイルが自動的に使用されます。


そこで、今回のアプリケーションでは、英語をデフォルトの言語とし、英語の
プロパティー・ファイルをMessageResources.propertiesとします。
そして、日本語のプロパティー・ファイルはMessageResources_ja.properties
とします。
(先ほどの国コードを使ってイギリス英語用にMessageResources_en_GB.properties
という名前のファイルを用意し、アメリカ英語はデフォルトと考えて
MessageResources.propertiesファイルに収めるというように、英語もさらに細分化
することも可能ですが、これは読者の自由課題とし、ここでは割愛します。)



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆


では、上記の話だけでは分かりにくいと思うので、実際にStrutsShopの最初の
WebページであるitemSelect.jspを国際化しながら説明していきましょう。


まず、現状のitemSelect.jspファイルの中身を下に提示します。
(プロジェクト・エクスプローラー内でStrutsShop配下のWebContent配下
のitemSelect.jspを開いて下さい。)

--------------------------------------------------------
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-nested" prefix="nested" %>

<html:html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
      <title>商品の検索</title>
   </head>
   <body bgcolor="#77ffff" text="#fa5a00">
      <h1>商品の検索</h1>
      <html:form method="POST" action="/itemlist">
         <logic:match name="exceptionInfo" value="systemerror">
            <logic:redirect page="/systemerror.jsp"/>
         </logic:match>

         <logic:notMatch name="exceptionInfo" value="systemerror">
            キーワード(商品名の一部)やカテゴリーを入力し、「商品検索」ボタンをクリックしてください。
            <br>
            <br>
            キーワード:<html:text property="keyword" size="20" />
            <br>
            カテゴリー:
            <html:select property="categoryNum">
               <html:options collection="categoryList" property="num" labelProperty="name" />
            </html:select>
            <br>
            <br>
            <html:submit property="submit" value="商品検索" />
         </logic:notMatch>
      </html:form>
   </body>
</html:html>
--------------------------------------------------------

国際化のためには、この中の日本語の文字列(メッセージ)を他の言語に切り替えられる
ようにする必要がありますから、

(タイトルの)商品の検索
(見出しの)商品の検索
キーワード(商品名の一部)やカテゴリーを入力し、「商品検索」ボタンをクリックしてください。
キーワード:
カテゴリー:
(submitボタンの)商品検索

という文字列を日本語と英語で切り替えられるようにしてみましょう。


そのためには、まず次のようにして、日本語のプロパティー・ファイルと英語の
プロパティー・ファイルを作ります。

(1) itemSelect.jspファイルにおいて、日本語の部分をそれぞれ

(タイトルの)商品の検索
     ↓
<bean:message key="itemSelect.title" />

(見出しの)商品の検索
     ↓
<bean:message key="itemSelect.title" />

キーワード(商品名の一部)やカテゴリーを入力し、「商品検索」ボタンをクリックしてください。
     ↓
<bean:message key="itemSelect.statement" />

キーワード:
     ↓
<bean:message key="itemSelect.keyword" />

カテゴリー:
     ↓
<bean:message key="itemSelect.category" />

というように書き換えます。

ここまでは、単純に日本語の部分をbean:messageタグに書き換える
だけで済みますが、最後のsubmitボタンの「商品検索」だけは扱い
が少し違ってきます。

submitボタンの「商品検索」という文字列はvalue属性の値として
指定されていますが、value属性の値の部分をbean:messageタグに
書き換えることはできませんので、このような場合は代わりに

<html:submit property="submit" value="商品検索" />

という行全体を
     ↓
<html:submit property="submit"><bean:message key="itemSelect.search" /></html:submit>

というように書き換えます。



以上でitemSelect.jspファイル全体は下記のようになります。

--------------------------------------------------------
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-nested" prefix="nested" %>

<html:html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
      <title><bean:message key="itemSelect.title" /></title>
   </head>
   <body bgcolor="#77ffff" text="#fa5a00">
      <h1><bean:message key="itemSelect.title" /></h1>
      <html:form method="POST" action="/itemlist">
         <logic:match name="exceptionInfo" value="systemerror">
            <logic:redirect page="/systemerror.jsp"/>
         </logic:match>

         <logic:notMatch name="exceptionInfo" value="systemerror">
            <bean:message key="itemSelect.statement" />
            <br>
            <br>
            <bean:message key="itemSelect.keyword" /><html:text property="keyword" size="20" />
            <br>
            <bean:message key="itemSelect.category" />
            <html:select property="categoryNum">
               <html:options collection="categoryList" property="num" labelProperty="name" />
            </html:select>
            <br>
            <br>
            <html:submit property="submit"><bean:message key="itemSelect.search" /></html:submit>
         </logic:notMatch>
      </html:form>
   </body>
</html:html>
--------------------------------------------------------

(編集がおわったら保管しておきましょう。)


(2) 先ほどbean:messageタグで指定した各キーに対する値(メッセージ)を
下記のようにしてプロパティー・ファイルに設定します。

(2-1) プロジェクト・エクスプローラー内でStrutsShop配下の「Javaリソース: src」
の配下のMessageResources.propertiesファイルをLimyプロパティー・エディターで
開きます。

(2-2) MessageResources.propertiesファイルの末尾に下記の6行を追加しましょう。

--------------------------------------------------------
# -- StrutsShop itemSelect --
itemSelect.title=商品の検索
itemSelect.statement=キーワード(商品名の一部)やカテゴリーを入力し、「商品検索」ボタンをクリックしてください。
itemSelect.keyword=キーワード:
itemSelect.category=カテゴリー:
itemSelect.search=商品検索
--------------------------------------------------------

念のため、この追加を行った後のMessageResources.propertiesファイル全体を下記に
提示します。

--------------------------------------------------------
# -- standard errors --
errors.header=<font color="#ff0000"><b>
errors.prefix=
errors.suffix=<br><br>
errors.footer=</b></font>
# -- validator --
errors.invalid={0} is invalid.
errors.maxlength={0} can not be greater than {1} characters.
errors.minlength={0} can not be less than {1} characters.
errors.range={0} is not in the range {1} through {2}.
errors.required={0} is required.
errors.byte={0} must be an byte.
errors.date={0} is not a date.
errors.double={0} must be an double.
errors.float={0} must be an float.
errors.integer={0} must be an integer.
errors.long={0} must be an long.
errors.short={0} must be an short.
errors.creditcard={0} is not a valid credit card number.
errors.email={0} is an invalid e-mail address.
# -- other --
errors.cancel=Operation cancelled.
errors.detail={0}
errors.general=The process did not complete. Details should follow.
errors.token=Request could not be completed. Operation is not in sequence.
# -- welcome --
welcome.title=Struts Blank Application
welcome.heading=Welcome!
welcome.message=To get started on your own application, copy the struts-blank.war to a new WAR file using the name for your application. Place it in your container's "webapp" folder (or equivalent), and let your container auto-deploy the application. Edit the skeleton configuration files as needed, restart your container, and you are on your way! (You can find the application.properties file with this message in the /WEB-INF/src/java/resources folder.)
# -- StrutsShop order --
errors.order.quantity.required=購入個数に空文字が入力されましたが、受け付けられません。
errors.order.quantity.integer=購入個数に数字以外の文字が入力されましたが、受け付けられません。
errors.userid.required=ユーザーIDを入力する必要があります。
errors.password.required=パスワードを入力する必要があります。
errors.name.required=お名前を入力する必要があります。
errors.zipcode.required=郵便番号を入力する必要があります。
errors.address.required=ご住所を入力する必要があります。
errors.telNo.required=お電話番号を入力する必要があります。
errors.emailAddress.required=Eメール・アドレスを入力する必要があります。
errors.membership.mustselected=会員登録に関する項目(「会員登録済み」など)を選択する必要があります。
# -- StrutsShop itemSelect --
itemSelect.title=商品の検索
itemSelect.statement=キーワード(商品名の一部)やカテゴリーを入力し、「商品検索」ボタンをクリックしてください。
itemSelect.keyword=キーワード:
itemSelect.category=カテゴリー:
itemSelect.search=商品検索
--------------------------------------------------------

なお、Limyプロパティー・エディターを使うと、画面上では日本語の文字が表示されて
もファイルに保管したときには自動的にUnicodeエスケープに変換されていますので、
自分で変換を行う必要はありません。(何の話かわからない人は、vol.145とvol.196
を復習のこと。)


(3) これらの日本語のメッセージを英語にしたファイルも作成しておく必要が
ありますので、それを用意しましょう。

(3-1) まず、プロジェクト・エクスプローラー内のStrutsShop(プロジェクト)配下
の「Javaリソース: src」配下のMessageResources.propertiesを右クリックし、
「コピー」を選択します。

(3-2) 再度、StrutsShop(プロジェクト)配下の「Javaリソース: src」配下の
MessageResources.propertiesを右クリックし、「貼り付け」を選択します。

(3-3) 「名前の競合」ウインドウが開いたら、名前を

MessageResources_ja.properties

に修正し、「OK」ボタンをクリックします。

これで、MessageResources.propertiesに並んでMessageResources_ja.properties
ファイルが作成されましたが、現時点では両方とも同じ内容です。
MessageResources_ja.propertiesファイルもLimyプロパティー・エディターで
開いて内容を確認して下さい。

(ちなみにこのMessageResources.propertiesファイルや
MessageResources_ja.propertiesファイルはTomcatにデプロイ
するときにはWEB-INFディレクトリー配下のclassesディレクトリー
の配下に置くことになります。)

このうち、コピー元のMessageResources.propertiesファイルのほうを
下記のように英語の内容に書き換えましょう。

(3-4) MessageResources.propertiesファイルの中の日本語の部分を英語に書き換えて
全体としては下記のようにしてみて下さい。

--------------------------------------------------------
# -- standard errors --
errors.header=<font color="#ff0000"><b>
errors.prefix=
errors.suffix=<br><br>
errors.footer=</b></font>
# -- validator --
errors.invalid={0} is invalid.
errors.maxlength={0} can not be greater than {1} characters.
errors.minlength={0} can not be less than {1} characters.
errors.range={0} is not in the range {1} through {2}.
errors.required={0} is required.
errors.byte={0} must be an byte.
errors.date={0} is not a date.
errors.double={0} must be an double.
errors.float={0} must be an float.
errors.integer={0} must be an integer.
errors.long={0} must be an long.
errors.short={0} must be an short.
errors.creditcard={0} is not a valid credit card number.
errors.email={0} is an invalid e-mail address.
# -- other --
errors.cancel=Operation cancelled.
errors.detail={0}
errors.general=The process did not complete. Details should follow.
errors.token=Request could not be completed. Operation is not in sequence.
# -- welcome --
welcome.title=Struts Blank Application
welcome.heading=Welcome!
welcome.message=To get started on your own application, copy the struts-blank.war to a new WAR file using the name for your application. Place it in your container's "webapp" folder (or equivalent), and let your container auto-deploy the application. Edit the skeleton configuration files as needed, restart your container, and you are on your way! (You can find the application.properties file with this message in the /WEB-INF/src/java/resources folder.)
# -- StrutsShop order --
errors.order.quantity.required=Purchase quantity is required.
errors.order.quantity.integer=Purchase quantity must be a number.
errors.userid.required=User ID is required.
errors.password.required=Password is required.
errors.name.required=Name is required.
errors.zipcode.required=Zip code is required.
errors.address.required=Address is required.
errors.telNo.required=Telephone number is required.
errors.emailAddress.required=E-mail address is required.
errors.membership.mustselected=You must select a registration-related term, e.g. "Already Registered", etc.
# -- StrutsShop itemSelect --
itemSelect.title=Search Items
itemSelect.statement=Enter a keyword or select a category, then push "Search" button.
itemSelect.keyword=Keyword:
itemSelect.category=Category:
itemSelect.search=Search
--------------------------------------------------------

以上で、itemSelect.jspの国際化の作業が終了しました。
(itemSelect.jsp以外のJSPファイルの国際化については、読者の自由課題
とし、当記事では省略させていただきます。)



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆


では、テストしてみましょう。
念のため、Tomcatの開始から手順を書いておきます。

(1) Eclipseの「サーバー」ビューの中の「ローカル・ホストのTomcat v5.5サーバー」
を右クリックし、「開始」を選択します。しばらくして、

ローカル・ホストのTomcat v5.5サーバー[始動済み,同期済み]

というように、後ろに「始動済み」の表示が出たら、Tomcatの起動が完了しています。

(2) Webブラウザー(Internet Explorer)を起動して、下記のようにして
デフォルトの言語を変更しましょう。

(2-1) Internet Explorerのメニュー・バーから「ツール」→「インターネットオプション」
を選択します。

(2-2) 「インターネットオプション」ウインドウの「全般」タブ配下の「言語」ボタン
をクリックします。

(2-3) 「言語の優先順位」ウインドウが開き、その「言語」欄には

日本語 [ja]

だけが入っている(Internet Explorerのバージョンによって表記が多少違う場合
もあるが似たようなものが入っている)ことと思いますので、「追加」ボタンを
クリックして、リストの中から

英語(米国)[en-US]

を選択(Internet Explorerのバージョンによって表記が多少違う場合もあるが
似たようなものを選択)し、「OK」ボタンをクリックすることによって英語を
追加して下さい。
(すでに英語が「言語」欄に入っている場合はそのままでいいです。)

(2-4) 「言語」欄の中の

英語(米国)[en-US]

を選択し、「上へ」ボタンをクリックすることによって、英語をリストの一番上に
移動して下さい。

そして、その「言語の優先順位」ウインドウの「OK」ボタンをクリックし、
「インターネットオプション」ウインドウも「OK」ボタンをクリックして
閉じます。

以上の操作によって、このWebブラウザーは英語環境のWebブラウザーに
なります。


(3) では、いつものようにURL

http://localhost:8080/StrutsShop/itemSelect.jsp

を入力しましょう。

どうでしょう。英語のWebページが開きますね。
これは(米国などの)英語環境のWebブラウザーで開いたときに英語のWebページが
開くことを意味します。


(4) では、以下の手順で日本語環境のWebブラウザーに戻しましょう。

(4-1) Internet Explorerのメニュー・バーから「ツール」→「インターネットオプション」
を選択します。

(4-2) 「インターネットオプション」ウインドウの「全般」タブ配下の「言語」ボタン
をクリックします。

(4-3) 「言語の優先順位」ウインドウが開いたら、その「言語」欄の中の

日本語 [ja]

を選択し、「上へ」ボタンをクリックすることによって、日本語をリストの一番上に
移動して下さい。

その「言語の優先順位」ウインドウの「OK」ボタンをクリックし、
「インターネットオプション」ウインドウも「OK」ボタンをクリックして
閉じます。

(5) そして、先ほどのURL

http://localhost:8080/StrutsShop/itemSelect.jsp

を再読み込みしましょう。

今度は日本語のWebページが開きますね。



以上で、国際化の機能がちゃんと働いていることが確認できました。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆


さて、ここまでStrutsによるJSPファイルの国際化の方法をお話してきましたが
これだけではまだ完璧ではありません。
完璧にするためにはJava自体の国際化の仕組みもお話しする必要がありますが、
これについてはまた後ほどまとめてお話します。お楽しみに。



◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆ ◆


(次回に続く)



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      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) 2010 Future Lifestyle Inc. 不許無断複製