様々なロケールをサポートするグローバル・インターネット・アプリケーションを構築するには、適切な開発の実施が必要です。ロケールとは、各国の言語およびその言語が話される地域のことです。アプリケーション自体で、ユーザーのロケール設定を認識し、ユーザーが期待する文化的な慣習に従って、内容を表示する必要があります。正しい日付書式や数値書式を使用するなど、適切なロケール特性でデータを表示することが重要です。Oracle Databaseは完全に国際化されており、グローバル・アプリケーションを開発およびデプロイするためのグローバル・プラットフォームを提供します。
この章では、JavaおよびOracle Database環境でのグローバル・アプリケーション開発について説明します。グローバル・インターネット・アプリケーションの開発およびデプロイに関連する基本タスク、すなわちロケール認識の開発、ユーザー設定言語でのHTMLコンテンツの構築、ユーザー・ロケールの文化的な慣習に従ったデータの表示などについて説明します。
この章では、次の項目について説明します。
グローバル・インターネット・アプリケーションでは、ユーザー・ロケールを認識する必要があります。日付、時間、通貨の書式設定など、ロケールに依存する機能はJavaやSQLなどのプログラミング環境に組み込まれています。アプリケーションではロケールに依存する機能を使用して、ユーザー・ロケールの文化的な慣習に従って、HTMLページを書式設定できます。
プログラミング環境によって、ロケールを表す方法は異なります。たとえば、フランス語(カナダ)のロケールは、次のように表されます。
環境 | 表記 | ロケール | 説明 |
---|---|---|---|
Java | Javaロケール・オブジェクト | fr_CA |
Javaでは、ISOの言語コードおよび国コードを使用します。
|
SQLおよびPL/SQL | NLS_LANGUAGE およびNLS_TERRITORY パラメータ |
NLS_LANGUAGE ="CANADIAN FRENCH"
|
『Oracle Database 2日で開発者ガイド』の第8章「グローバル環境での作業」も参照してください。 |
表9-1に、一般的に使用されるロケールのJavaおよびOracle環境での定義を示します。
表9-1 Java、SQLおよびPL/SQLプログラミング環境でのロケール表記
ロケール | Java | NLS_LANGUAGE、NLS_TERRITORY |
---|---|---|
中国語(中国) |
|
|
中国語(台湾) |
|
|
英語(アメリカ) |
|
|
英語(イギリス) |
|
|
フランス語(カナダ) |
|
|
フランス語(フランス) |
|
|
ドイツ語(ドイツ) |
|
|
イタリア語(イタリア) |
|
|
日本語(日本) |
|
|
韓国語(韓国) |
|
|
ポルトガル語(ブラジル) |
|
|
ポルトガル語(ポルトガル) |
|
|
スペイン語(スペイン) |
|
|
異なるプログラミング環境をまたいでグローバル・アプリケーションを記述する場合、ユーザーのロケール設定を環境間で同期化する必要があります。たとえば、PL/SQLプロシージャをコールするJavaアプリケーションでは、Javaロケールを対応するNLS_LANGUAGE
およびNLS_TERRITORY
値にマッピングし、ユーザー・ロケールが一致するようにパラメータ値を変更してから、PL/SQLプロシージャをコールする必要があります。
Oracle Globalization Development Kit(GDK)では、LocaleMapper
クラスが提供されています。Java、IANA、ISO、Oracle間で、等価のロケールおよびキャラクタ・セットがマッピングされます。Javaアプリケーションが、Oracleロケール名で指定されたロケール情報をクライアントから受け取る場合があります。Javaアプリケーションで情報を正しく処理するには、等価のJavaロケールにマッピングできる必要があります。
例9-1に、LocaleMapper
クラスの使用方法を示します。
例9-1 JavaロケールからOracleの言語および地域へのマッピング
Locale locale = new Locale("fr", "CA"); String oraLang = LocaleMapper.getOraLanguage(locale); String oraTerr = LocaleMapper.getOraTerritory(locale);
GDKは、Oracleアプリケーション開発者にグローバル・インターネット・アプリケーションの開発フレームワークを提供する、一連のJava Application Program Interface(API)です。GDKによって、Javaの既存のグローバリゼーション機能が補完されます。中間層JavaアプリケーションとOracle Databaseサーバー間のロケール動作が同期化されます。
グローバル環境では、ロケール設定が異なるユーザーをアプリケーションで受け入れる必要がある場合があります。ユーザーの優先ロケールを判別します。優先ロケールがわかったら、アプリケーションはそのロケールの言語を使用してHTMLコンテンツを構築し、そのロケールの文化的な慣習に従う必要があります。
ユーザー・ロケールを判別する最も一般的な方法の1つは、ユーザーのブラウザのデフォルトのISOロケール設定に基づきます。通常、ブラウザはロケール設定をAccept-Language
HTTPヘッダーを使用してHTTPサーバーに送信します。このヘッダーがNULL
に設定されている場合、使用できるロケール設定情報がないため、アプリケーションは、理論上は事前定義されたアプリケーションのデフォルト・ロケールにフォールバックする必要があります。
JSPページとJavaサーブレットの両方で、例9-2に示すように、サーブレットAPIへのコールを使用してAccept-Language
HTTPヘッダーを取得できます。
例9-2 JavaでのAccept-Languageヘッダーを使用したユーザー・ロケールの判別
String lang = request.getHeader("Accept-Language") StringTokenizer st = new StringTokenizer(lang, ",") if (st.hasMoreTokens()) userLocale = st.nextToken();
このコードはAccept-Language
ヘッダーをHTTPリクエストから取得し、最初のISOロケールを抽出した後、そのISOロケールをユーザー設定ロケールとして使用します。
Javaロケール・オブジェクトは、対応するユーザーのロケールをJavaで表します。ロケールに使用されるJavaエンコーディングは、Java文字列とバイト・データ間で正しく変換する必要があります。Javaコードでユーザー・ロケールを認識する場合は、ロケールのJavaエンコーディングを考慮する必要があります。JavaメソッドでJavaロケールおよびエンコーディングを認識させるには、次の2つの方法があります。
メソッドのデフォルトのJavaロケールおよびデフォルトのJavaエンコーディングを使用する
メソッドのJavaロケールおよびJavaエンコーディングを明示的に指定する
グローバル・アプリケーションを開発する場合は、2番目の方法を採用し、現在のユーザー・ロケールに対応するJavaロケールおよびJavaエンコーディングを明示的に指定することをお薦めします。例9-3に示すように、getDateTimeInstance
メソッドで、ユーザー・ロケール(user_locale
)に対応するJavaロケール・オブジェクトを指定できます。
HTMLページのエンコーディングは、ブラウザおよびインターネット・アプリケーションにとって重要な情報です。ページ・エンコーディングは、インターネット・アプリケーションがサービスを提供するロケールに使用されるキャラクタ・セットです。ブラウザでは、正しいフォントおよびキャラクタ・セット・マッピング表を使用してHTMLページを表示できるように、ページ・エンコーディングを認識する必要があります。インターネット・アプリケーションでは、HTMLフォームからの入力を処理できるように、HTMLページ・エンコーディングを認識する必要があります。
異なるロケールに異なるネイティブ・エンコーディングを使用するかわりに、すべてのページ・エンコーディングにUTF-8(Unicodeエンコーディング)を使用することをお薦めします。UTF-8エンコーディングを使用すると、グローバル・アプリケーションのコーディングが簡単になるだけでなく、単一ページで多言語のコンテンツを配置できるようになります。
この項では、次の項目について説明します。
HTMLページのエンコーディングを指定するには、2つの方法があります。1つはHTTPヘッダーで指定する方法、もう1つはHTMLページ・ヘッダーで指定する方法です。
HTTPヘッダーでのエンコーディングの指定
Content-Type
HTTPヘッダーをHTTP指定に含めます。例9-4に示すように、コンテンツ・タイプおよびキャラクタ・セットを指定します。
charset
パラメータでは、HTMLページのエンコーディングを指定します。charset
パラメータに指定できる値は、ブラウザがサポートする文字エンコーディングのIANA名です。
HTMLページ・ヘッダーでのエンコーディングの指定
この方法は、主に静的なHTMLページに対して使用します。例9-5に示すように、HTMLヘッダーで文字エンコーディングを指定します。
charset
パラメータでは、HTMLページのエンコーディングを指定します。Content-Type
HTTPヘッダーと同様に、charsetパラメータに指定できる値は、ブラウザがサポートする文字エンコーディングのIANA名です。
contentType
ページ・ディレクティブを使用して、JavaServer Pages(JSP)ファイルのContent-Type
HTTPヘッダーでHTMLページのエンコーディングを指定できます。次に例を示します。
<%@ page contentType="text/html; charset=utf-8" %>
このエンコーディングは、クライアントへの応答用にJSPファイルが使用するMIME
タイプおよび文字エンコーディングです。JSPコンテナに有効な任意のMIME
タイプまたはIANAキャラクタ・セット名を使用できます。デフォルトのMIME
タイプはtext/html
であり、デフォルトのキャラクタ・セットはISO-8859-1です。前述の例では、キャラクタ・セットはUTF-8に設定されています。contentType
ページ・ディレクティブのキャラクタ・セットによって、JSPエンジンに対し、動的なHTMLページをエンコードし、指定されたキャラクタ・セットでHTTP Content-Type
ヘッダーを設定するように指示されます。
Javaサーブレットの場合、Servlet APIのsetContentType
メソッドをコールして、HTTPヘッダーでページ・エンコーディングを指定できます。例9-6のdoGet
関数は、このメソッドのコール方法を示しています。
例9-6 setContentTypeを使用したサーブレットでのページ・エンコーディングの指定
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // generate the MIME type and character set header response.setContentType("text/html; charset=utf-8"); ... // generate the HTML page Printwriter out = response.getWriter(); out.println("<HTML>"); ... out.println("</HTML>"); }
getWriter
メソッドは、setContentType
メソッド・コールで指定されたキャラクタ・セットを使用する出力ストリーム・ライターを初期化するので、getWriter
メソッドの前にsetContentType
メソッドをコールする必要があります。ライターに書き込まれ最終的にブラウザに書き込まれるすべてのHTMLコンテンツは、setContentType
コールで指定されたエンコーディングによってエンコードされます。
ユーザー・インタフェースをユーザーのローカル言語で表示できるようにすることは、アプリケーションのグローバル化に関する基本タスクの1つです。HTMLページのコンテンツの翻訳可能なソースは、次のカテゴリに分類されます。
アプリケーション・コード内にハードコードされたテキスト文字列
静的なHTMLファイル、イメージ・ファイル、テンプレート・ファイル(CSSなど)
データベースに格納された動的データ
この項では、翻訳可能なコンテンツの外部化について説明します。内容は次のとおりです。
JavaサーブレットとJSPページ内の翻訳可能な文字列をJavaリソース・バンドルに外部化して、これらのリソース・バンドルがJavaコードから独立して翻訳できるようにする必要があります。翻訳後、リソース・バンドルは英語のバンドルと同じベース・クラス名になりますが、Javaロケール名が接尾辞として付けられます。英語のリソース・バンドルと同じディレクトリにバンドルを配置して、Javaリソース・バンドルの参照メカニズムが正常に機能するようにする必要があります。
関連項目: Javaリソース・バンドルに関するSunのドキュメントを参照してください。
|
多言語アプリケーションではユーザー・ロケールは固定ではないため、ユーザー・ロケールに対応するJavaロケール・オブジェクトを明示的に指定し、getBundle
メソッドをコールする必要があります。次の例では、Javaロケール・オブジェクトはuser_locale
です。
ResourceBundle rb = ResourceBundle.getBundle("resource", user_locale); String helloStr = rb.getString("hello");
前述のコードは、ユーザー設定ロケールに対応するリソース・バンドルから、テキスト文字列hello
のローカライズされたバージョンを取得します。
HTMLやGIFなどの静的ファイルは、すぐに翻訳できます。これらのファイルを翻訳するときは、UTF-8をファイル・エンコーディングとして、対応する言語に翻訳する必要があります。翻訳されたファイルの言語を区別する場合、異なる言語の静的ファイルは異なるディレクトリに格納するか、または異なるファイル名で格納することができます。
JSPページを使用するかJavaサーブレットを使用するかに関係なく、製品名や製品の説明などの動的な情報は、多くの場合データベースに格納されています。様々な翻訳を区別するには、この情報を保持するデータベース・スキーマに情報の言語を示す列を含める必要があります。翻訳された情報を選択するには、問合せにWHERE
句を含めて、問合せの希望する言語で情報を選択する必要があります。
アプリケーション内のデータは、ユーザーが予期したとおりに表示される必要があります。そうでないと、データの意味が誤って解釈される可能性があります。たとえば、12/11/05は、アメリカ合衆国では2005年12月11日を意味するのに対して、イギリスでは2005年11月12日を意味します。このような混乱は、数値や通貨の書式にも存在します。たとえば、ピリオド(.)はアメリカ合衆国では小数区切りですが、ドイツでは3桁ごとの区切り文字として使用されています。
ソートのルールは言語によって異なり、アルファベットの文字の順序に従う言語、文字の画数に従う言語、単語の発音に従う言語などがあります。ユーザーが慣れている言語順序でソートされていないデータを表示すると、情報の検索が難しくなり、時間がかかることがあります。
アプリケーションのロジックおよびデータベースから取得されるデータ量によっては、アプリケーション・レベルではなくデータベース・レベルでデータを書式設定する方が適切な場合があります。Oracle Databaseには、ユーザーのロケール設定がわかっているときにデータの表示を調整するのに役立つ多くの機能があります。次の項では、SQLでのロケールに依存する操作の例について説明します。
Oracle Databaseには、3つの異なる日付表示書式があります。標準の日付、短い日付および長い日付です。例9-7に、アメリカ合衆国とドイツにおける短い日付書式と長い日付書式の違いを示します。
例9-7 ロケールによる日付書式の違い(アメリカ合衆国とドイツ)
SQL> ALTER SESSION SET NLS_TERRITORY=america NLS_LANGUAGE=american; Session altered. SQL> SELECT employee_id EmpID, 2 SUBSTR(first_name,1,1)||'.'||last_name "EmpName", 3 TO_CHAR(hire_date,'DS') "Hiredate", 4 TO_CHAR(hire_date,'DL') "Long HireDate" 5 FROM employees 6* WHERE employee_id <105; EMPID EmpName Hiredate Long HireDate ---------- --------------------------- ---------- ----------------------------- 100 S.King 06/17/1987 Wednesday, June 17, 1987 101 N.Kochhar 09/21/1989 Thursday, September 21, 1989 102 L.De Haan 01/13/1993 Wednesday, January 13, 1993 103 A.Hunold 01/03/1990 Wednesday, January 3, 1990 104 B.Ernst 05/21/1991 Tuesday, May 21, 1991 SQL> ALTER SESSION SET SET NLS_TERRITORY=germany NLS_LANGUAGE=german; Session altered. SQL> SELECT employee_id EmpID, 2 SUBSTR(first_name,1,1)||'.'||last_name "EmpName", 3 TO_CHAR(hire_date,'DS') "Hiredate", 4 TO_CHAR(hire_date,'DL') "Long HireDate" 5 FROM employees 6* WHERE employee_id <105; EMPID EmpName Hiredate Long HireDate ---------- --------------------------- -------- ------------------------------ 100 S.King 17.06.87 Mittwoch, 17. Juni 1987 101 N.Kochhar 21.09.89 Donnerstag, 21. September 1989 102 L.De Haan 13.01.93 Mittwoch, 13. Januar 1993 103 A.Hunold 03.01.90 Mittwoch, 3. Januar 1990 104 B.Ernst 21.05.91 Dienstag, 21. Mai 1991
例9-8に、アメリカ合衆国とドイツでの小数点文字とグループのセパレータの違いを示します。
例9-8 ロケールによる数値書式の違い(アメリカ合衆国とドイツ)
SQL> ALTER SESSION SET SET NLS_TERRITORY=america; Session altered. SQL> SELECT employee_id EmpID, 2 SUBSTR(first_name,1,1)||'.'||last_name "EmpName", 3 TO_CHAR(salary, '99G999D99') "Salary" 4 FROM employees 5* WHERE employee_id <105 EMPID EmpName Salary ---------- --------------------------- ---------- 100 S.King 24,000.00 101 N.Kochhar 17,000.00 102 L.De Haan 17,000.00 103 A.Hunold 9,000.00 104 B.Ernst 6,000.00 SQL> ALTER SESSION SET SET NLS_TERRITORY=germany; Session altered. SQL> SELECT employee_id EmpID, 2 SUBSTR(first_name,1,1)||'.'||last_name "EmpName", 3 TO_CHAR(salary, '99G999D99') "Salary" 4 FROM employees 5* WHERE employee_id <105 EMPID EmpName Salary ---------- --------------------------- ---------- 100 S.King 24.000,00 101 N.Kochhar 17.000,00 102 L.De Haan 17.000,00 103 A.Hunold 9.000,00 104 B.Ernst 6.000,00
スペインでは、従来から「ch」、「ll」および「ñ」を独自の文字として扱っており、順序としてはそれぞれc、lおよびnの後になります。例9-9に、従業員名ChenおよびChungに対してスペイン語のソートを使用した場合の結果を示します。
例9-9 言語ソートの違い(バイナリとスペイン語)
SQL> ALTER SESSION SET NLS_SORT=binary; Session altered. SQL> SELECT employee_id EmpID, 2 last_name "Last Name" 3 FROM employees 4 WHERE last_name LIKE 'C%' 5* ORDER BY last_name EMPID Last Name ---------- ------------------------- 187 Cabrio 148 Cambrault 154 Cambrault 110 Chen 188 Chung 119 Colmenares 6 rows selected. SQL> ALTER SESSION SET NLS_SORT=spanish_m; Session altered. SQL> SELECT employee_id EmpID, 2 last_name "Last Name" 3 FROM employees 4 WHERE last_name LIKE 'C%' 5* ORDER BY last_name EMPID Last Name ---------- ------------------------- 187 Cabrio 148 Cambrault 154 Cambrault 119 Colmenares 110 Chen 188 Chung 6 rows selected.
NLS_LANGUAGE
パラメータによって、データベースから返されるデータベース・エラー・メッセージの言語も制御されます。SQL文を送信する前にこのパラメータを設定すると、ローカル言語固有のデータベース・エラー・メッセージがアプリケーションに返されます。
次のサーバー・メッセージについて考えてみます。
ORA-00942: table or view does not exist
NLS_LANGUAGE
パラメータをフランス語に設定すると、サーバー・メッセージは次のように表示されます。
ORA-00942: table ou vue inexistante
関連項目: Oracle Databaseのグローバリゼーション・サポート機能の詳細は、『Oracle Database 2日で開発者ガイド』の「グローバル環境での作業」の章を参照してください。 |
Javaアプリケーションでは、リソース・バンドルを使用して、JSPページで使用される、ローカライズされた様々なテキストが提供されています。
リソース・バンドルには、ロケール固有のオブジェクトが含まれています。ロケール固有のリソース(ページに表示するテキストなど)がプログラムで必要な場合は、現在のユーザー・ロケールに適したリソース・バンドルからロードできます。この方法では、実際のテキストをリソース・バンドルに分離することによって、大部分がユーザー・ロケールから独立したプログラム・コードを記述できます。
リソース・バンドル・テクノロジには、次のような特徴があります。
リソース・バンドルは、メンバーで共通の基準名を共有するファミリに属しますが、名前にはロケールを示す構成要素も追加されます。たとえば、リソース・バンドルのファミリの基準名がMyResources
であるとします。ドイツ語のロケール固有のバージョンは、MyResources_de
などとなります。
ファミリ内の各リソース・バンドルには同じ項目が含まれていますが、項目はそのリソース・バンドルによって表されるロケール用に翻訳されています。たとえば、あるボタンで使用されるString
は、MyResources
ではCancel
と定義されていますが、MyResources_de
ではAbbrechen
と定義されている場合があります。
異なる国の異なるリソースを特殊化できます。たとえば、スイス(CH
)のドイツ語(de
)などです。
アプリケーションでリソース・バンドルを使用するには、次の手順を実行します。
リソース・バンドルを作成します。
ビジュアル・コンポーネントがあるページで、そのページで使用するリソース・バンドルを識別します。
ページに表示するテキストの各項目について、ハードコードされたテキストを使用するかわりに、リソース・バンドルからテキストを取得します。
関連項目: リソース・バンドルに関するSunのドキュメントを参照してください。
|
サンプル・アプリケーションでは、次の場所でリソース・バンドルを使用できます。
JSPページの見出しおよびラベル。この場合、ページでテキストを直接入力するのではなく、スクリプトレットを使用してテキストを検索できます。
ボタンなどのコントロールの値。この場合、ボタンのvalue
プロパティを、リソース・バンドルからテキストを取得する式に設定します。
この項では、次のタスクについて説明します。
デフォルトのリソース・バンドルを作成するには、次の手順を実行します。
クラスjava.util.ListResourceBundle
を拡張する新しいJavaクラスMyResources.java
を作成します。
リソース・バンドル・クラスおよび内容を返すメソッドを次のように定義します。
public class MyResources extends ListResourceBundle { public Object[][] getContents() { return contents; } static final Object[][] contents = { }; }
ページに含めるテキスト項目1つに対してエントリを1つ追加し、キーおよびキーのテキストを指定します。たとえば次の例では、他の言語に翻訳する必要のある文字列をコメントで示しています。
static final Object[][] contents = { // LOCALIZE THIS {"CompanyName", "AnyCo Corporation"}, {"SiteName", "HR Application"}, {"FilterButton", "Filter"}, {"UpdateButton", "Update"}, // END OF MATERIAL TO LOCALIZE };
完成したリソース・バンドル・クラスは、例9-10のようになります。
例9-10 リソース・バンドル・クラスの作成
public class MyResources extends ListResourceBundle { public Object[][] getContents() { return contents; } static final Object[][] contents = { // LOCALIZE THIS {"CompanyName", "AnyCo Corporation"}, {"SiteName", "HR Application"}, {"FilterButton", "Filter"}, {"UpdateButton", "Update"}, // END OF MATERIAL TO LOCALIZE }; }
アプリケーションをグローバル化するには、サポートする様々なロケールについて、各言語での項目のテキストを含む、ロケール固有のリソース・バンドルを作成する必要があります。
リソース・バンドルで定義されたテキストをJSPページで使用するには、次の手順を実行します。
使用するJSPページ(edit.jsp
など)をビジュアル・エディタで開きます。
ページの一番上で最初の見出しの前に新しい行を作成し、行の「スタイル」をNone
に設定します。jsp:usebeanタグを新しい行に追加します。IDとしてmyResources
を入力し、クラスとしてhr.MyResources
を入力します。「有効範囲」を「セッション」
に設定し、「OK」をクリックします。
jsp:scriptletをページにドラッグします。ページの見出しなど、リソース・バンドル・テキストを表示する場所にドラッグします。
「スクリプトレットの挿入」ダイアログ・ボックスで、次のように、リソース・バンドルからテキストを取得するスクリプトを入力します。
out.println(myResources.getString("CompanyName") + ": " + myResources.getString("SiteName"));
見出しにすでにテキストが表示されていた場合は、ここで削除できます。
ビジュアル・エディタの下の「ソース」タブを選択すると、次のようなページのコードが表示されます。
<h2 align="center"> <% = myResources.getString("CompanyName") + ": " + myResources.getString("SiteName")); %> </h2>
リソース・バンドル・テキストをボタンのラベルとして使用するには、ビジュアル・エディタでボタンをダブルクリックします。ボタンのプロパティ・ダイアログ・ボックスで、ボタンの「値」パラメータに、次のようなスクリプトを入力します。
<% out.println(myResources.getString("UpdateButton"));%>
ページのソース・コードを表示すると、次のようなコードが表示されます。
<input type="submit" value=<% out.println(myResources.getString("UpdateButton"));%> />
ここでアプリケーションを実行すると、リソース・バンドルで定義したテキストがページに表示されます。