Strutsを使ったWebアプリケーションの作成方法について説明してきた本連載も、いよいよ最終回となります。今回は、最後のテーマとして、前回「Validatorプラグインによる妥当性検証の実現(後編)」完成させた「書籍登録・更新アプリケーション」を国際化(i18n)対応させる方法を説明します。
昨今では、Webサイトを日本語/英語など複数の言語に対応させたいという要件は珍しいものではありません。最初は日本語だけのページでも、その後のビジネス展開によっては、後から複数の言語に対応したいという追加要望が上がってくることもあるでしょう。あるいは、最初は日本語/英語に対応していたものを、中国語/ドイツ語にも対応させたいというような状況もあるかもしれません。
このようなケースで、JSPファイルやアプリケーションコード、あるいは設定ファイルなどに言語固有の情報(例えば、項目名などの固定値)を直接記述(ハードコーディング)するのは好ましいことではありません。というのも、もしも後から英語対応のページを構築しようとした場合、コード中に日本語などが直接記述されていると、すべてのJSPファイルやアプリケーションコード、設定ファイルを表示させたい言語の数だけ多重化しなければならなくなってしまうからです。
さらに、こうした作業も大変なことには違いないのですが、「開発して、終わり」というアプリケーションならまだマシです。苦労するのは、開発中のわずかな間だけなのですから。しかし、多くのアプリケーションは、リリース後にも機能追加、改定やバグフィックスなどの修正が付きまといます。そのような場合にも、言語の数だけ多重化されたコードをすべて修正し、テストしなければならないとしたら、これはとても現実的な話ではありません。
そこで必要となるのが、アプリケーションの「国際化対応」なのです。アプリケーションを国際化対応させることで、このような多重化による問題を解決することができます。国際化対応を行うと、具体的には、以下のような日本語表記の画面があったとします。
日本語表記の画面
上記の画面をブラウザの言語設定を変更して表示すると、以下のような英語表記に動的に切り替わって表示されるというものです。
動的に切り替わった英語表記の画面
既存のアプリケーションを国際化対応させる場合、その作業は大きく2つのステップに分けることができます。
- 既存のアプリケーションから言語依存の要素を取り除く
- 言語依存の要素をメッセージリソースとしてまとめる
このステップを念頭に置いて、「書籍登録・更新アプリケーション」を例にアプリケーションの国際化対応をさせる手順を説明していきます。
国際化対応の第一歩は、ユーザーインターフェイスであるJSPファイルから言語依存の要素を取り除くことです。まず、以下のように変更してJSPファイル内にハードコーディングされている日本語を取り除きます。なお、JSPファイルそのものの構造については、連載各回の解説を参照してください。
BookView.jsp |
<%@ page contentType="text/html;charset=Windows-31J" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<html:html>
<head>
<title><bean:message key="books.title" /></title>
</head>
<body>
<h1 >
<bean:message key="books.title" /></h1>
[<html:link action="/BookWriteViewAction">
<bean:message key="books.title.new" /></html:link>]
<table border="1">
<tr bgcolor="#EEeeEE">
<th><bean:message key="books.header.title" /></th>
<th><bean:message key="books.header.author" /></th>
<th><bean:message key="books.header.price" /></th>
<th><bean:message key="books.header.publish" /></th>
<th><bean:message key="books.header.published" /></th>
</tr>
<logic:iterate id="bookInfo" name="book.view.info"
scope="request">
<tr>
<td nowrap>
<html:link action="/BookWriteViewAction"
paramId="isbn" paramName="bookInfo" paramProperty="isbn">
<bean:write name="bookInfo" property="title" />
</html:link>
</td>
<td nowrap><bean:write name="bookInfo"
property="author" /></td>
<td nowrap><bean:write name="bookInfo"
property="price" />
<bean:message key="books.header.currency" /></td>
<td nowrap><bean:write name="bookInfo"
property="publish" /></td>
<td nowrap><bean:write name="bookInfo"
property="published" /></td>
</tr>
</logic:iterate>
</table>
</body>
</html:html> |
BookUpdate.jsp |
<%@ page contentType="text/html;charset=Windows-31J" %>
<%@ taglib uri="/tags/struts-html" prefix="html" %>
<%@ taglib uri="/tags/struts-bean" prefix="bean" %>
<%@ taglib uri="/tags/struts-logic" prefix="logic" %>
<html:html>
<head>
<title><bean:message key="books.title" /></title>
</head>
<body>
<h1 >
<bean:message key="books.title" /></h1>
<html:javascript formName="BookUpdateForm" />
<html:form action="/BookWriteAction"
onsubmit="return validateBookUpdateForm(this)">
<table border="0">
<tr>
<th align="right"><bean:message key="books.header.isbn" />:</th>
<td>
<logic:equal name="update.flag" value="true">
<html:text property="isbn" size="20" maxlength="20"
readonly="true" />
</logic:equal>
<logic:notEqual name="update.flag" value="true">
<html:text property="isbn" size="20" maxlength="20" />
</logic:notEqual>
</td>
</tr>
<tr>
<th align="right"><bean:message key="books.header.title" />:</th>
<td>
<html:text property="title" size="50" maxlength="50" />
</td>
</tr>
<tr>
<th align="right"><bean:message key="books.header.author" />:</th>
<td>
<html:text property="author" size="15" maxlength="15" />
</td>
</tr>
<tr>
<th align="right"><bean:message key="books.header.price" />:</th>
<td>
<html:text property="price" size="5" maxlength="5" />
<bean:message key="books.header.currency" />
</td>
</tr>
<tr>
<th align="right"><bean:message key="books.header.publish" />:</th>
<td>
<html:text property="publish" size="25" maxlength="25" />
</td>
</tr>
<tr>
<th align="right"><bean:message
key="books.header.published" />:</th>
<td>
<html:text property="published" size="12" maxlength="12" />
</td>
</tr>
<tr>
<td colspan="2">
<html:submit property="submit">
<bean:message key="books.header.submit" /></html:submit>
<html:reset property="reset">
<bean:message key="books.header.reset" /></html:reset>
</td>
</tr>
</table>
</html:form>
<html:errors />
</body>
</html:html> |
注目してほしいのは、赤字で記述されたbean:message要素の部分です。bean:message要素は、後述するメッセージリソースから指定された文字列を取り出し、ページ内に埋め込むためのものです。key属性には、メッセージリソース内の該当するメッセージキーを指定します。
例えば、
<bean:message key="books.header.author" /> |
という記述があった場合、リソースファイルで定義されたキー“books.header.author”に対応する値で、この部分が動的に置き換えられるというわけです。
国際化対応させるには、まず日本語部分をすべてこのbean:message要素で置き換えます。ただし、BookUpdate.jspのhtml:submit要素やhtml:reset要素など、value属性の値として日本語が埋め込まれている要素については、単純に属性値をbean:message要素で置き換えることはできません。これらの要素については、value属性を取り除いたうえで、bean:message要素をhtml:submit要素やhtml:reset要素配下のコンテンツとして指定します。