blob: da286e9e7751fc502fc4947c743df72a389ee9b1 [file] [log] [blame]
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
= NetBeans Eコマース チュートリアル - 言語サポートの追加
:jbake-type: tutorial
:jbake-tags: tutorials
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: NetBeans Eコマース チュートリアル - 言語サポートの追加 - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, NetBeans Eコマース チュートリアル - 言語サポートの追加
この単元の目標は、Webアプリケーションの言語サポートを有効にする方法を説明することです。「言語サポート」とは、ここでは顧客が指定した言語に応じてページビューを表示することを指します。`AffableBean` アプリケーションのコンテキスト内で、以前のlink:design.html#requirements[+お客様のご要望+]の概略にあったように、我々は英語とチェコ語の両方のサポートを提供することで合意しました。
これを達成するために、あなたは国際化のための Java サポートを使います。あなたは各言語用に_resource bundle_(リソースバンドル)を作成します。そして、Java ランタイム環境が着信したクライアントリクエストのために適切な言語を決定できるようにします。また、ユーザーが手動で言語を切り替えできるようにする「言語切り替え」を実装します。
NetBeans IDE は、アプリケーション コンテンツのローカライズのための特別サポートを提供しています。これには Customizer (カスタマイザー)ダイアログが含まれており、あなたは既存のリソースバンドルのベース名に新しいロケール(言語)を追加できます。同様に、特別のプロパティエディターも含まれており、あなたはテーブル レイアウトの中のすべてのロケールの key-value pairs (キーと値のペア)を見たり追加したりできます。これらはどちらもこのチュートリアルで利用します。
あなたはこのチュートリアルで構築するアプリケーションのライブデモを見ることができます: link:http://services.netbeans.org/AffableBean/[+NetBeans Eコマース チュートリアル デモアプリケーション+]。
|===
|ソフトウェアまたはリソース |必須バージョン
|link:https://netbeans.org/downloads/index.html[+NetBeans IDE+] |Java バンドル版, 6.8 又は 6.9
|link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+Java Development Kit (JDK)+] |バージョン 6
|GlassFish サーバー |v3 又は Open Source Edition 3.0.1
|link:http://dev.mysql.com/downloads/mysql/[+MySQL データベースサーバー+] |バージョン 5.1
|link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot8.zip[+AffableBean プロジェクト+] |スナップショット 8
|link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot9.zip[+AffableBean プロジェクト+] |スナップショット 9
|===
*ノート:*
* NetBeans IDE を正常に実行するには Java 開発キット(JDK)が必要です。上記のリソースがなにもない場合は、あなたは JDK を最初にダウンロードしてインストールする必要があります。
* NetBeans IDE Java バンドル版には、このチュートリアルで構築するアプリケーションに必要な Java Web JAVA EE 技術が含まれています。
* NetBeans IDE Java バンドル版もまた、このチュートリアルに必要な GlassFish サーバーを含んでいます。あなたはlink:http://glassfish.dev.java.net/public/downloadsindex.html[+個別に GlassFish サーバーをダウンロード+]できますが、しかし、NetBeans の提供するバージョンをダウンロードすれば自動的に IDE に登録される利点があります。
* あなたは、以前の単元を完了することなく、このチュートリアルの単元を追いかけることができます。そうするにはlink:setup.html[+セットアップ手順+]を参照してください。そこには、データベースを準備する方法や、IDE GlassFish MySQL 間の接続を確立する方法が説明されています。
[[resourceBundles]]
== リソースバンドルを理解する
Java では、リソースバンドルはlink:http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/ResourceBundle.html[+`java.util.ResourceBundle`+] クラスの表現です。Javadoc で述べられたように、
[NOTE]
====
リソースバンドルはロケール固有のオブジェクトを含んでいます。プログラムがロケール固有のリソースを必要とするとき、例として文字列、あなたのプログラムは現在のユーザーのロケールに適したリソースバンドルから、それをロードすることができます。この方法で、リソースバンドルの中のロケール固有の情報全てではないが、ユーザーのロケールからほとんど隔離した、大部分が独立したプログラムコードを書くことができます。
これにより、あなたはプログラムを書くことができます:
* _簡単にローカライズされるか、異なる言語に翻訳されるか_
* _一度に複数のロケールを処理する_
* _さらにロケールをサポートするように後から簡単に変更できる_
====
Javadoc から、`ResourceBundle`は、 link:http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/ListResourceBundle.html[+`ListResourceBundle`+] と link:http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/PropertyResourceBundle.html[+`PropertyResourceBundle`+]の両方の親であることに注意します。このチュートリアルでは、我々は `PropertyResourceBundle` を利用して、リソースを`.properties` 拡張子を使ったテキストファイルとして管理します。そしてそれには、キーと値のペアの形式でロケール固有の情報が入っています。新しい各翻訳では、リソースバンドルの新バージョンは、ロケール識別子をアンダースコア('`_`')を使用したベース名へ追加することで作成されます。たとえば、このチュートリアルで作成する2つのリソースバンドルの抜粋版は次のようになります:
*messages_en.properties*
[source,java]
----
meats=meats
bakery=bakery
----
*messages_cs.properties*
[source,java]
----
meats=maso
bakery=pečivo
----
上記の例で、「`messages`」はベース名を表しています。そしてロケール識別子は、アンダースコアでつなげられた2文字のコードです。 (つまり、'`en`' は英語で、'`cs`' はチェコ語です) 。2文字のコードは、言語の名前を表すコードのリストである国際標準 link:http://en.wikipedia.org/wiki/ISO_639[+ISO 639+] がもとになっています。ISO 639 標準は link:http://www.w3.org/International/[+W3C 国際活動+]で採用されており、 すべての主要なブラウザで使用されています。(これらはコードであり、`Accept-Language` HTTPヘッダーで解釈されます)。また link:http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/java/util/Locale.html[+`java.util.Locale`+] クラスにも内蔵されています。
[[multilingual]]
== 多言語対応ページを作成する
`AffableBean` アプリケーションに戻り、顧客との継続的な協議を経て以下の実装の詳細について合意しました:
* ウェブサイトは、最初にユーザーブラウザの優先言語に基づいて表示される。
* ブラウザの優先言語が英語でもチェコ語でもないときは、サイトは英語のテキストを表示します。
* ページヘッダー内の「language toggle(言語切り替え)」により、ユーザーが言語を変更できるオプションがある。
* 「言語切り替え」を使用して言語を変更するときは、ユーザーは同じページビューにとどまる。
* 「言語切り替え」は確認ページに表示されてはならない。ユーザーはチェックアウトする前に、彼または彼女の言語を既に選択しているので。
上記の点を実装するためにタスクを2つの部分に分割します。ページビューの基本的なバイリンガル(二か国語)サポートの作成から始めます。バイリンガル サポートを所定の位置に一度配置すると、「言語切り替え」が実装され、ユーザーが手動で言語を切り替えることができるようになります。
3つの基本的な手順があり、あなたの Web ページに多言語サポートを組み込むために、あなたはこの手順に従う必要があります。
1. あなたがサポートする予定の各言語のリソースバンドルを作成します。
[start=2]
. アプリケーションのリソースバンドルを登録するには、web.xml のデプロイメント記述子の中にコンテキストパラメータを設定します。
[start=3]
. ページビューで、 hard-coded(ハードコーディングされた)」テキストをリソースバンドルの中のキーを参照する `<fmt:message>` タグに置き換えます。
次の演習では、上記の3つの手順を適用して、`AffableBean` welcome ページに英語とチェコ語のサポートを統合する方法をデモします。そして Firefox を使用してブラウザの言語サポートでテストする方法を示して完了します。
1. <<createResource,リソースバンドルを作成する>>
[start=2]
. <<register,アプリケーションにリソースバンドルを登録する>>
[start=3]
. <<replace,「ハードコード化された」テキストを「`<fmt:message>`」タグに置換する>>
[start=4]
. <<test,サポートされた言語をテストする>>
[[createResource]]
=== リソースバンドルを作成する
1. AffableBean プロジェクトのlink:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot8.zip[+スナップショット8+]を IDE で開きます。[Open Project(プロジェクトを開く)] ( image::images/open-project-btn.png[] )ボタンをクリックして、ウィザードを使用して、プロジェクトをダウンロードしたコンピュータの場所を指示します。
[start=2]
. [Run Project(プロジェクトを実行)]( image::images/run-project-btn.png[] )ボタンをクリックしてプロジェクトを実行し、それが適切にデータベースとアプリケーションサーバーに設定されるようにします。
プロジェクトを実行してエラーを受け取った場合、link:setup.html[+セットアップ手順+]を再度見ます。そこには、データベースを準備し IDE GlassFish MySQL 間の接続を確立する方法について説明されています。
[start=3]
. デフォルトのリソースバンドルの作成から始めて、ページビューで使用されるテキストを格納します。IDE のツールバーの [New File(新規ファイル)]( image::images/new-file-btn.png[] ) ボタンをクリックします。(または、Ctrl-n キーを押します。Macでは ⌘-N )。
[start=4]
. [Categories(カテゴリ)] の下の [Other(その他)] を選択し、 [File Types(ファイルの種類)] の下の [ Properties File (プロパティファイル)] を選択します。
image::images/new-file-wzd.png[title="Create a new resource bundle using the File wizard"]
注。このウィザードは、選択した [file type(ファイルの種類)] の説明を提供しています:
[NOTE]
====
resource bundle(.properties) ファイルを作成してアプリケーションを国際化します。そのためにあなたのコードから目に見える全てのテキスト文字列を分離します。リソースバンドル ファイルは、Antスクリプトのプロパティのような、他の種類の文字列を収集することにも使用できます。作成されたリソースバンドルはロケールを一つだけ含みますが、あなたは、作成したファイルのコンテキストメニューからロケールを追加することもできます。バンドルは、特定のロケール用のテキストファイル(プロパティファイル形式)の中で編集されるか、またはすべてのロケールの情報を表示するテーブルの中で編集されることができます。
====
[start=5]
. [次へ]をクリック。[Name and Location(名前と場所)] のステップで、File Name(ファイルの名前)]に [`messages` ]、 [Folder field(フォルダのフィールド)] [`src/java/resources`] と入力します。これは、[`resources`]と名づけた新しいパッケージの中にリソースバンドルを配置するようウィザードに指示しています。
image::images/new-properties-file-wzd.png[title="Specify the name and location of the resource bundle"]
[start=6]
. [Finish]をクリックします。 [ Messages.properties ] リソースバンドルが生成され、エディタに開きます。
注意。前述したように、新しい `messages.properties` ファイル名には、それに付加された言語コードがありません。これは次の理由によるものです。このファイルは_default_(デフォルト)のリソースバンドルとして使用されるためです。デフォルトのリソースバンドルが適用されるのは、Javaランタイム環境が要求されたロケールに直接マッチするものを見つけられない時です。
[start=7]
. プロジェクトの `index.jsp` ファイルをエディタで開きます。次のテキストが現在使用されていることに注意してください:
* *Greeting:* `Welcome to the online home of the Affable Bean Green Grocer.`
(ごあいさつ: ようこそ愛想のよいビーンのグリーン食料品店オンラインホームへ。)
* *Introductory Message:* `Enjoy browsing and learning more about our unique home delivery service bringing you fresh organic produce, dairy, meats, breads and other delicious and healthy items to your doorstep.`
welcome メッセージ: ブラウズしてお楽しみ下さい。そして私たちの独自の宅配サービスについて知ってください。新鮮な有機農産物、乳製品、肉、パン、他のおいしい健康商品をお客様の玄関までお届けするサービスです
また注意して下さい。`index.jsp` がブラウザでレンダリングされる時に、表示される4つのカテゴリの言語固有の名前が必要になります。これらの名前は現在データベースから取得されるので、私たちはリソースバンドルのキーとしてそれらを使用することができます。
<<impDeets,「実装の詳細」>>の一つを思い出して下さい。上記の状態は「ブラウザの優先言語が英語でもチェコ語でない場合は、英語のテキストでサイトが表示される。」です。; したがって、我々が `messages.properties` ファイルに適用する値は英語になります。
[start=8]
. `messages.properties` ファイルの中に、welcome ページで使用されるテキストのキーと値のペアを追加することから始めます。以下の内容を追加します。
[source,java]
----
# welcome page
greeting=Welcome to the online home of the Affable Bean Green Grocer.
introText=Our unique home delivery service brings you fresh organic produce, dairy, meats, breads and other delicious and healthy items direct to your doorstep.
# categories
dairy=dairy
meats=meats
bakery=bakery
fruit\ &amp;\ veg=fruit &amp; veg
----
コメントは番号記号('`#`')を使って追加します。また、`fruit &amp; veg` カテゴリ名にはスペースが含まれているためスペース文字はバックスラッシュ('`\`')を使いエスケープする必要があります。そしてリソースバンドルのキーとしてその名前を使用します。
今、我々はアプリケーションの welcome ページのデフォルトのリソースバンドルを完了しました。次は、お客様が指定した言語のリソースバンドルを引き続き作成しましょう。
[start=9]
. プロジェクトウィンドウで、[Source Packages(ソースパッケージ)] ノードを展開し、[`resources`] > [`messages.properties`] ファイルノードで右クリックし、 [Customize (カスタマイズ)]を選択します。[Customizer(カスタマイザ)] ダイアログが開きます。
[start=10]
. カスタマイザのダイアログで、[Add Locale(ロケールの追加)]ボタンをクリックします。[New Locale(新しいロケール)]ダイアログボックスが表示され、[Language Code(言語コード) ] コンボ ボックスで[ '`en`' ] を入力して、[ OK ] をクリックします。
image::images/new-locale-dialog.png[title="The New Locale dialog enables you to add a new locale to an existing resource bundle base name"]
言語と地域の両方に、_locale_(ロケール) が定義されます。地域を指定するために使われるオプションの country コードは、日付、時刻、数値、および通貨の書式を定義するために適用されます。詳細については、技術資料、link:http://java.sun.com/developer/technicalArticles/J2SE/locale/[+「Javaプラットフォームのロケールを理解する」+]を参照してください。
[start=11]
. [Add Locale(ロケールの追加)]ボタンをもう一度クリックし、次に、[Language Code(言語コード)]コンボボックスに[ `cs` ]と入力し、[OK]をクリックします。カスタマイザのダイアログが次のように表示されます。
image::images/customizer-dialog.png[title="The New Locale dialog enables you to add a new locale to an existing resource bundle base name"]
[start=12]
. [Close(閉じる)]をクリックします。プロジェクトウィンドウで、リソースバンドルが次のように見えることに注意してください。あなたはリソースバンドルを展開して、それに含まれているキーを表示することができます。
image::images/projects-window.png[title="View resource bundles and the keys they contain in the Projects window"]
[start=13]
. 3つのリソースバンドルのいずれかを右クリックし、[ Open(オープン)]を選択します。プロパティエディタが開き、あなたはテーブルレイアウトですべてのロケールのキーと値のペアを見ることも編集することもできます。
IDE 内でウィンドウを最大化するためには、Shift-Esc キーを押します。
注意。あなたはカスタマイザダイアログを使用して新しいロケールを追加すると、前の手順で英語とチェコ語でやったように、デフォルトのリソースバンドルのキーと値は、新しいロケールにコピーされます
[start=14]
. チェコ語リソースバンドルの値を変更します。これをするには、各行のテーブルのセルの中をクリックして直接あなたのエントリを入力するか、または、編集したいセルを選びプロパティエディタの下部にある *Value* フィールドに入力するか、どちらかの方法を使います。
* *greeting:* `Vítejte v našem domácím on-line obchodě Affable Bean Green Grocer.`
* *introText:* `Naše jedinečná dodávková služba Vám zajistí dopravu čerstvých organických produktů, mléčných výrobků, uzenin, pečiva a dalších delikates a zdravých výroků až ke dveřím.`
* *dairy:* `mléčné výrobky`
* *meats:* `maso`
* *bakery:* `pečivo`
* *fruit &amp; veg:* `ovoce a zeleniny`
また、各キーと値のペアにコメントを追加することができます。プロパティエディタの *Comment* フィールドに入力した全てのテキストは、リソースバンドルのテキストファイルにコメントとしてキーと値のペアの上に追加されます。(すなわち、'`#`' 記号の後に続けて)。
[start=15]
. プロジェクトウィンドウ内の `messages_cs.properties` ファイルノードをダブルクリックします。テキストファイルはプロパティエディタであなたの変更に応じて更新されていることに注意して下さい。
[source,java]
----
# welcome page
greeting=Vítejte v našem domácím on-line obchodě Affable Bean Green Grocer.
introText=Naše jedinečná dodávková služba Vám zajistí dopravu čerstvých organických produktů, mléčných výrobků, uzenin, pečiva a dalších delikates a zdravých výroků až ke dveřím.
# categories
dairy=mléčné výrobky
meats=maso
bakery=pečivo
fruit\ &amp;\ veg=ovoce a zeleniny
----
今、私たちは以下の定義されたリソースバンドルを持っています:
* default (English)
* Czech
* English
デフォルトのバンドルが英語の場合、明示的に英語のリソースバンドルを作成する必要はないとあなたは思うかもしれません。ただし、次のシナリオを考えてみます:クライアントブラウザの優先言語のリストに、チェコ語、英語の両方が含まれており、チェコ語より英語を優先しています。もしアプリケーションが英語のリソースバンドルを提供せずチェコ語を提供している場合は、ページはブラウザにチェコ語を送信します。(チェコ語バンドルが定義されているので)。これは明らかにそのブラウザの目的の動作ではありません。
[[register]]
=== アプリケーションでリソースバンドルを登録する
この手順の目的は、JSTL 形式の情報を提供することです。(すなわち、link:http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/fmt/tld-summary.html[+`fmt`+]) タグライブラリはアプリケーション内にあるどんなリソースバンドルを見つけることができます。これを達成するために、既存のリソースバンドルを使用して、アプリケーションに link:http://download.oracle.com/docs/cd/E17477_01/javaee/5/jstl/1.1/docs/api/javax/servlet/jsp/jstl/fmt/LocalizationContext.html[+`LocalizationContext`+] を作成するように指示します。アプリケーションの `web.xml` デプロイメント記述子にコンテキストパラメータを設定することによってこれを行うことができます。
コンテキストパラメータを設定する話題については、link:connect-db.html#param[+「データベースへのアプリケーションの接続」+]でカバーしています。
1. プロジェクトウィンドウで、[Configuration Files(構成ファイル)]ノードを展開して、`web.xml` をダブルクリックしエディタに開きます。
[start=2]
. デプロイメント記述子の[General(全般)]タブでの下に、[Context Parameters(コンテキストパラメータ)]カテゴリを展開します。
[start=3]
. Add (追加)」ボタンをクリックし、[Add Context Parameter (コンテキストパラメータの追加)] ダイアログの中で次の値を入力します。
* *Parameter Name:* `javax.servlet.jsp.jstl.fmt.localizationContext`
* *Parameter Value:* `resources.messages`
image::images/add-context-parameter.png[title="Add context parameters under the General tab for web.xml"]
`LocalizationContext` クラスは、`javax.servlet.jsp.jstl.fmt` パッケージに所属しています。あなたは、link:http://java.sun.com/products/jsp/jstl/1.1/docs/api/index.html[+JSTLの1.1 APIリファレンス+] オンラインを見ることによってこれを確認することができます。
[start=4]
. [OK] をクリックします。新しいコンテキストパラメータは[General(全般)]タブの下の既存のコンテキストパラメータのテーブルに追加されます。
[start=5]
. デプロイメント記述子の XML タブをクリックします。以下のエントリがそのファイルに追加されていることに注意します:
[source,xml]
----
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.messages</param-value>
</context-param>
----
[[replace]]
=== ハードコード化されたテキストを `<fmt:message>` タグに置き換える
リソースバンドルのローカライズされたテキストをお客様のウェブページに適用するために、あなたが作成したキーと値のペアからキーを参照します。JSTL `<fmt:message>` タグを使用して、あなたはキーを参照することができます。
1. プロジェクトの `index.jsp` ページをエディタに開きます。(もし既に開いている場合は、Ctrl-Tabを押し、そのファイルに切り替えます。
[start=2]
. ページの左側の列に表示されているハードコードされたテキストのインスタンスを削除しその場所に `<fmt:message>` タグを入力します。こうするために、 `key` 属性を使いリソースバンドルのキーを指示します。ページの左側の列は次のようになります。
[source,html]
----
<div id="indexLeftColumn">
<div id="welcomeText">
<p style="font-size: larger">*<fmt:message key='greeting'/>*</p>
<p>*<fmt:message key='introText'/>*</p>
</div>
</div>
----
[start=3]
. 4つのカテゴリの名前に `<fmt:message>` タグを追加します。しかし、`key` 属性の値として、`${category.name}` 式を使用します。カテゴリ名は、`<img>` タグの `alt`(代替)属性の値としても使用されるので、同じ手順に従います。ページの右の列は次のようになります。
[source,html]
----
<div id="indexRightColumn">
<c:forEach var="category" items="${categories}">
<div class="categoryBox">
<a href="<c:url value='category?${category.id}'/>">
<span class="categoryLabel"></span>
<span class="categoryLabelText">*<fmt:message key='${category.name}'/>*</span>
<img src="${initParam.categoryImagePath}${category.name}.jpg"
alt="*<fmt:message key='${category.name}'/>*" class="categoryImage">
</a>
</div>
</c:forEach>
</div>
----
[start=4]
. 最後に、Web ページに `fmt` タグライブラリが宣言されていることを確認します。そのファイルの先頭に次のように入力してください:
[source,java]
----
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
----
*注:* ここでは、あなたはタグライブラリの宣言を `index.jsp` ファイルの先頭に追加します。しかし、プロジェクトのほかの場所で `<fmt>` タグを使い始めるときは、個々のページビューからタグライブラリ宣言を削除する方が理にかなっているかもしれません。そして、それをヘッダ(`header.jspf`)ファイルに追加します。このようなやり方はlink:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot9.zip[+「 スナップショット 9」+](およびそれ以降のスナップショット)で採用しています。
これで、アプリケーションのウェルカムページへバイリンガルのサポートを提供するための必要なタスクを完了しました。次の手順では、お使いのブラウザで言語サポートをテストする方法をデモします。
[[test]]
=== サポートされた言語をテストする
あなたは理論的には、アプリケーションでサポートされた言語を含む以下のシナリオをテストできるだけでなく、サポートされていない言語も同様にテストすることができます(例えば、韓国語)。:
|===
|Use-case |Outcome
1. Browser has no preferred language |English displays
2. Browser prefers only English |English displays
3. Browser prefers only Czech |Czech displays
4. Browser prefers only Korean |English displays
5. Browser prefers Korean and English; Korean takes precedence |English displays
6. Browser prefers Korean and English; English takes precedence |English displays
7. Browser prefers Korean and Czech; Korean takes precedence |Czech displays
8. Browser prefers Korean and Czech; Czech takes precedence |Czech displays
9. Browser prefers English and Czech; English takes precedence |English displays
|10. Browser prefers English and Czech; Czech takes precedence |Czech displays
|11. Browser prefers, in the following order, English, Czech, Korean |English displays
|12. Browser prefers, in the following order, English, Korean, Czech |English displays
|13. Browser prefers, in the following order, Czech, English, Korean |Czech displays
|14. Browser prefers, in the following order, Czech, Korean, English |Czech displays
|15. Browser prefers, in the following order, Korean, English, Czech |English displays
|16. Browser prefers, in the following order, Korean, Czech, English |Czech displays
|===
16のシナリオをステップ実行するよりもむしろ、我々は上記のシナリオ3を調べる方法をデモします。ここには、ブラウザの優先言語はチェコ語で Firefox ブラウザを使用しています。
1. Firefox で、 [ツール] > [オプション] Macでは、 [Firefox] > [Preferences(設定)])を選択します。表示されたウィンドウで、 [ Content (コンテンツ)]タブをクリックします。
image::images/firefox-content.png[title="Examine your browser's preferred languages"]
[start=2]
. [Languages(言語)]見出しの下で、[Choose]をクリックします。
[start=3]
. 用意されたテキストエリアに現在リストされた任意の言語を選択して、[ Remove(削除)]をクリックします。 (あなたの言語のリストを覚えておいてください、そしてこのチュートリアルを完了後に言語を元に戻してください。
[start=4]
. 'Select Language to Add' (言語を選択して追加する)]ドロップダウンをクリックして、 `Czech [cs]` を選択します。そして、[ Add (追加)]ボタンをクリックします。 Czech language (チェコ語) がテキストエリアに追加されます。
image::images/firefox-languages.png[title="Specify your browser's preferred languages"]
[start=5]
. [OK]をクリックして、Esc キーを押し Firefoxの[Options(オプション)]ウィンドウを閉じます。
[start=6]
. プロジェクトを実行します( image::images/run-project-btn.png[] )。welcome ページがブラウザに開き、テキストがチェコ語で表示されることに注意してください。
image::images/czech-text.png[title="The displayed language is determined by your browser's language preferences"]
[[toggle]]
== Language Toggle(言語切り替え)」を実装する
今、基本的なチェコ語-英語サポートができました。続けて、アプリケーションのページビューで「言語切り替え」を実装します。我々はこのタスクを3つの部分に分けることができます:
* <<toggleDisplay,「Toggle Display切り替え表示」を作成しブラウザの優先言語と同期する>>
* <<handleRequest,「言語切り替え」からのリクエストを処理する機能を実装する>>
* <<keepTrack,アプリケーションが元のページビューの追跡を保持できるようにする>>
[[toggleDisplay]]
=== 切り替え表示を作成しブラウザの優先言語と同期する
1. Go to File]ダイアログを使用して、`header` JSP のフラグメントをエディターに開きます。Alt-Shift-O Ctrl-Shift-O Macの場合)キーを押し、ダイアログで「 h と入力し、[OK]をクリックします。
image::images/go-to-file-dialog.png[title="Use the Go to File dialog to quickly open project resources in the editor"]
[start=2]
. `header.jspf` ファイルで、最初の `<div class="headerWidget">` タグを見つけます( 56行)。そして、`[ language toggle ]`(言語切り替え) プレースホルダのテキストを以下のHTMLマークアップに置き換えます。
[source,html]
----
<div class="headerWidget">
*<%-- language selection widget --%>
english | <div class="bubble"><a href="chooseLanguage?language=cs"esky</a></div>*
</div>
----
このマークアップは、英語が表示言語の時の「言語切り替え」の外観を実装します。言い換えれば、[切り替え]は、ユーザーがチェコ語(すなわち、 '`česky`' )オプションを選択できるリンクを提供します。リンクはリクエストを送信するために使用され、そしてリクエストされた言語コードを指定するクエリ文字列 (`?language=cs`)を作成します。
*注:* ユニット5 link:page-views-controller.html#controller[+「 ページビューとコントローラサーブレットの準備」+]を思い出して、`ControllerServlet` が `/chooseLanguage` URLパターンを処理するように設定します。
上記の実装で、[ '`rounded`' ]クラスをトグルリンクに適用します。スナップショット8には、link:http://jquery.com/[+jQuery+] の JavaScriptのライブラリが含まれています。そして、Webサイトの外観と動作を強化するさまざまなUI効果を活用します。 link:http://plugins.jquery.com/project/validate[+クライアント側のjQueryプラグインの検証+] (link:transaction.html#client[+前の単元+]で議論しました)は別として、スナップショットは link:http://plugins.jquery.com/project/corners[+角丸用のプラグイン+]を実装しています。プラグインには`rounded`(丸みを帯びさせる)クラスが必要で、HTML要素に丸みを帯びた角の効果をつけるためのクラスです。その他の効果もまた適用されています。welcomeページのカテゴリ見出しの緩和効果だけでなく、カテゴリページのカテゴリボタンにも適用されています。構成はプロジェクトのスナップショットの `header.jspf` に実装されています。 /p>
[start=3]
. プロジェクトを実行 ( image::images/run-project-btn.png[] ) して、トグルがブラウザでどのように見えるか確認します。
image::images/language-toggle.png[title="Run the project to view the language toggle"]
現在のところ、「言語切り替え」は、どの言語でページが表示されていても、上の画像のように表示されます。次のステップで JSTL ロジックをトグルの中に統合します。そして、ページに表示された言語に応じてレンダリングされるようにします。
[start=4]
. トグル実装を次のように変更します。
[source,html]
----
<div class="headerWidget">
<%-- language selection widget --%>
*<c:choose>
<c:when test="${pageContext.request.locale.language ne 'cs'}">
english
</c:when>
<c:otherwise>
<c:url var="url" value="chooseLanguage">
<c:param name="language" value="en"/>
</c:url>
<div class="bubble"><a href="${url}">english</a></div>
</c:otherwise>
</c:choose> |
<c:choose>
<c:when test="${pageContext.request.locale.language eq 'cs'}">
česky
</c:when>
<c:otherwise>
<c:url var="url" value="chooseLanguage">
<c:param name="language" value="cs"/>
</c:url>
<div class="bubble"><a href="${url}"esky</a></div>
</c:otherwise>
</c:choose>*
</div>
----
上記の実装で、あなたは JSTL `core` タグライブラリからの条件タグを頼りに、リクエストロケールで使われる言語に対応したトグルの左と右の部分を表示します。"リクエストロケールで使用される言語はなんですか?。リクエストがされたとき、ブラウザは `Accept-Language` HTTP ヘッダー内の優先ロケールのリストを渡します。 サーバー上のJavaランタイム環境はそのリストを読み取り、アプリケーションのリソースバンドルで定義されたロケールに基づいて最も一致するものを決定します。そして、この一致したものは `ServletRequest` オブジェクトに記録され、`getLocale` メソッドからアクセスすることができます 。たとえば、次のステートメントでサーブレットから優先ロケールにアクセスすることができます。
[source,java]
----
request.getLocale();
----
あなたは、IDEのHTTPモニター([ウィンドウ] > [デバッグ] > [HTTPサーバモニタ])を使用して、クライアントのリクエストのHTTPヘッダを調べることができます。HTTPモニターを使用するには、あなたが使用しているサーバーでHTTPモニターを最初にアクティブ化することが必要です。ユニット8、link:manage-sessions.html[+セッション管理+] サブセクションの下の link:manage-sessions.html#http-monitor[+クライアントサーバ間通信をHTTPモニタで調べる+] でデモを提供しています。
優先ロケールの言語を決定するために、`Locale` クラスの'`getLanguage`’メソッドを使用します。繰り返しますが、サーブレットから、次のように、クライアント リクエストの優先ロケールの言語にアクセスすることができます。
[source,java]
----
request.getLocale().getLanguage();
----
`header.jspf` フラグメントへあなたが追加した実装に戻り、あなたは`pageContext.request` 暗黙オブジェクトを利用して、与えられたクライアントのリクエスト用の `ServletRequest` へアクセスします。ドット表記を使用して、その後、あなたがサーブレットからしたように、同じメソッドの呼び出しをします。上記の例で「リクエストロケールで使用される言語」へアクセスするのは以下のように簡単です:
[source,java]
----
${pageContext.request.locale.language}
----
*注:* 上記の実装は、`<c:url>` タグを使用してトグルリンクをセットアップしています。これは、セッショントラッキングの手段としてURL書き換えが使用されるイベントの中でリクエストURLを正しくエンコードするために行われます。ユニット8、link:manage-sessions.html#encodeUrl[+セッション管理+] に「 `<c:url>` タグの使われ方」の簡単な説明が載っています。
[start=5]
. 基本的な言語のテストを `header.jspf` ファイルに追加します。これで、私たちが「クライアントリクエストの優先言語に応じてトグルが正常にレンダリングされるかどうか」を確認できるようになります。ページの `<body>` タグの後に次を入力します。
[source,html]
----
<body>
*<%-- Language test --%>
<p style="text-align: left;"><strong>tests:</strong>
<br>
<code>\${pageContext.request.locale.language}</code>: ${pageContext.request.locale.language}
</p>*
<div id="main">
----
[start=6]
. あなたはブラウザの優先言語としてチェコ語を設定していることを確認し。 (あなたがこのチュートリアルの単元通りに実行している場合は、すでにこれを行っています。もしそうでない場合は、上記<<test,「サポートされた言語をテストする」>>に概説されている手順を参照して下さい。)
[start=7]
. プロジェクトを実行しますimage::images/run-project-btn.png[] )。そしてブラウザでアプリケーションの welcome ページを調べます。
image::images/language-test.png[title="Language toggle displays according to request's preferred language"]
お使いのブラウザの優先言語がチェコ語に設定されている場合は、次のことに注意してください:
* 我々が前の手順で紹介したテストでは「cs」が優先言語であると示しています。
* チェコ語テキストがページに表示されます。
* 言語切り替えは、ユーザが英語を選択できるリンクを提供しています。
[[handleRequest]]
=== 「言語切り替え」からのリクエストを処理する機能を実装する
今、トグルは所定の位置にあり、ページに表示される言語に対応してトグルが表示されます。続いて、`ControllerServlet` へユーザーが言語切り替えのリンクをクリックした時にリクエスト送信を行うコードを追加します。
上記<<step4,ステップ 4>>から、ここまでの言語切り替えの実装で示したように、クエリ文字列の付いたリクエストされた URL は次のようになります:
* *English:* `chooseLanguage?language=en`
* *Czech:* `chooseLanguage?language=cs`
私たちの目標は選択した言語を登録して、次にページビューと選択した言語に基づいた「言語切り替え」の両方を表示することです。 我々は、クエリ文字列から `language` パラメータを抽出することによりこれを達成することができます。そしてユーザーが選択した言語を記憶しているセッションスコープ `language` 属性を作成します。 その後、我々は `header.jspf` フラグメントに戻ります。そして link:http://download-llnw.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/fmt/setLocale.html[+`<fmt:setLocale>`+] タグにユーザーの選択に基づいたページ言語を設定します。 `<fmt:setLocale>` タグで、我々はページ表示に使用される言語を手動で切り替えることができます。 我々は、また、言語切り替えを変更します。そして、もし`language`(言語)属性が既に設定されている場合、トグルの外観は `language` 属性の値に応じて決定されます。
1. `ControllerServlet` をエディタで開きます。「Go To File(ファイルに移動)」ダイアログを使い(Alt-Shift-O(Ctrl -Shift-O Macの場合)を押し)、「'`controller`'」と入力し、「 OK」をクリックします。開いたファイルで、`chooseLanguage` リクエストを処理する `doGet` メソッドの部分を探します。( 126行) 。
[start=2]
. 「`// TODO: Implement language request`」コメントを削除します。リクエストのクエリ文字列から `language` パラメーターを抽出するコードを入力します。
[source,java]
----
// if user switches language
} else if (userPath.equals("/chooseLanguage")) {
*// get language choice
String language = request.getParameter("language");*
}
----
[start=3]
. リクエストスコープの `language` を探し、以下を追加します。
[source,java]
----
// if user switches language
} else if (userPath.equals("/chooseLanguage")) {
// get language choice
String language = request.getParameter("language");
*// place in request scope
request.setAttribute("language", language);*
}
----
[start=4]
. 一時的な措置として、言語切り替えリンクがクリックされた時、レスポンスをwelcomeページの`index.jsp` へ転送するようにアプリケーションにもたせます。次のコードを追加します。
[source,java]
----
// if user switches language
} else if (userPath.equals("/chooseLanguage")) {
// get language choice
String language = request.getParameter("language");
// place in request scope
request.setAttribute("language", language);
*// forward request to welcome page
try {
request.getRequestDispatcher("/index.jsp").forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
return;*
}
----
当然のことながら、彼または彼女がどのページにいるかに関わらずユーザを welcome ページに転送することが、「言語切り替え」動作を処理する望ましい方法ではありません。我々は次のサブセクション<<keepTrack,Enable the Application to Keep Track of the Originating Page View>>(アプリケーションが元のページビューのトラックを保持することを可能にする。)でこの問題を再度扱います。しかしながら、その間にも、この方法でプロジェクトを実行して、私たちは現在の言語切り替えの実装の結果を確認できます。
[start=5]
. `header.jspf` フラグメントに切り替えて(もしファイルがエディターに既に開いている場合は、Ctrl-Tab を押して、そのファイルを選択します。)、link:http://download-llnw.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/fmt/setLocale.html[+`<fmt:setLocale>`+]タグを、新しい`language`変数に基づいたページ言語を設定するために適用します。以下を追加します。
[source,xml]
----
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
*<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%-- Set language based on user's choice --%>
<c:if test="${!empty language}">
<fmt:setLocale value="${language}" scope="session" />
</c:if>*
<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
----
`language` 変数は、ユーザーが言語切り替えのリンクをクリックするときだけに作成されるので、あなたは link:http://download-llnw.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/c/if.html[+`<c:if>`+] タグを使ってテストを実行して、言語を設定する前にその変数があるかどうか見つけ出します。 `<fmt:setLocale>` タグを適用する時、あなたはそのスコープ(範囲)をセッションに設定します。あなたが、ウェブサイトで彼または彼女のセッションの残りの部分でユーザーが選択した言語を優先したいので。また、これがヘッダで `fmt` ライブラリが初めて使用されるため、あなたはタグライブラリを宣言します。
あなたは EL `${!empty language}` を次のように読むことができます。「language 変数が null または空の文字列」の場合は False。他の利用可能な例については、link:http://download-llnw.oracle.com/javaee/5/tutorial/doc/bnahq.html#bnaim[+Java EE 5チュートリアル: EL 式の例+] を見てください。
[start=6]
. 言語切り替えの実装を変更します。そして、`<fmt:setLocale>` タグによって値がすでに設定されている場合、トグルはその値に指定された言語に従い表示します。(あなたは、`${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}` 式を使用して、この値を調べることができます。)
現在の実装を `<c:choose>` タグで囲みます。そして、ロケールが手動で設定されているイベントの中に、現在の実装と同様にロジックを作成します。(変更は太字で表示されています。)
[source,html]
----
<div class="headerWidget">
<%-- language selection widget --%>
*<c:choose>
<%-- When user hasn't explicitly set language,
render toggle according to browser's preferred locale --%>
<c:when test="${empty sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}">*
<c:choose>
<c:when test="${pageContext.request.locale.language ne 'cs'}">
english
</c:when>
<c:otherwise>
<c:url var="url" value="chooseLanguage">
<c:param name="language" value="en"/>
</c:url>
<div class="bubble"><a href="${url}">english</a></div>
</c:otherwise>
</c:choose> |
<c:choose>
<c:when test="${pageContext.request.locale.language eq 'cs'}">
česky
</c:when>
<c:otherwise>
<c:url var="url" value="chooseLanguage">
<c:param name="language" value="cs"/>
</c:url>
<div class="bubble"><a href="${url}"esky</a></div>
</c:otherwise>
</c:choose>
*</c:when>
<%-- Otherwise, render widget according to the set locale --%>
<c:otherwise>
<c:choose>
<c:when test="${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session'] ne 'cs'}">
english
</c:when>
<c:otherwise>
<c:url var="url" value="chooseLanguage">
<c:param name="language" value="en"/>
</c:url>
<div class="bubble"><a href="${url}">english</a></div>
</c:otherwise>
</c:choose> |
<c:choose>
<c:when test="${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session'] eq 'cs'}">
česky
</c:when>
<c:otherwise>
<c:url var="url" value="chooseLanguage">
<c:param name="language" value="cs"/>
</c:url>
<div class="bubble"><a href="${url}"esky</a></div>
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>*
</div>
----
[start=7]
. ブラウザでプロジェクトを調べる前に、 `<fmt:setLocale>` タグで設定された値を表示するテストを別に追加します。以前に作成したテストの下に、次のコードを追加します。
[source,xml]
----
<p style="text-align: left;"><strong>tests:</strong>
<br>
<code>\${pageContext.request.locale.language}</code>: ${pageContext.request.locale.language}
*<br>
<code>\${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}</code>: ${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}*
</p>
----
`javax.servlet.jsp.jstl.fmt.locale.session` は、`<fmt:setLocale>` タグでセットされた `Locale`(ロケール)用の文字列リテラルキーです。エディタの左マージンでクリックして、新しいテスト上にブレークポイントを設定( image::images/breakpoint-badge.png[] )して、これを確認することができます。プロジェクトでデバッガ( image::images/debug-project-btn.png[] ) を実行します。ブラウザで言語を変更するトグルリンクをクリックして、デバッガがブレークポイントで中断した時に、変数ウィンドウ(Alt-Shift-1; Ctrl-Shift-1 Mac)を調べます。
このチュートリアルで表わされる EL 式は、主に、ドット(`.`) 表記を使用しています。上記の式に描かれた形式は、ブラケット (`[]`) 表記として知られています。それを使い、あなたは文字列リテラルのキーを引用符内に入力して、オブジェクトの値を抽出します。:
[source,java]
----
${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}
----
多数の EL リゾルバクラスは、式を解決する目的のために存在します。たとえば、上記の式がランタイムで検出されたとき、 link:http://download-llnw.oracle.com/javaee/6/api/javax/servlet/jsp/el/ImplicitObjectELResolver.html[+`ImplicitObjectResolver`+] はセッションスコープ属性名にその値をマップした Map を最初に返します。(変数ウィンドウの上記画像で、そのセッションの属性が link:http://download-llnw.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html[+`ConcurrentHashMap`+] の中に保持されていることを確認できます。)。式の残りの部分を解決するために link:http://download-llnw.oracle.com/javaee/6/api/javax/el/MapELResolver.html[+`MapELResolver`+] が使われて、['`javax.servlet.jsp.jstl.fmt.locale.session`'] という名前のキーの値を取得します。
より詳細については、これを参照してください。Java EE 5 チュートリアル:link:http://download-llnw.oracle.com/javaee/5/tutorial/doc/bnahq.html#bnaif[+統一表現言語:式の解決+]
[start=8]
. プロジェクトを実行( image::images/run-project-btn.png[] )します。ブラウザでアプリケーションの welcome ページを調べます。
image::images/toggle-page1.png[title="Welcome page displays according to browser's preferred language"]
上の画像では、サーバーは `Accept-Language` HTTP ヘッダーからブラウザの優先言語としてチェコ (`cs`) を識別しています。これは最初のテストで指示したものです。チェコ語のページが表示され、言語の切り替えで、ユーザは英語を選択することができます。 `<fmt:setLocale>` タグがまだ呼び出されていないので、2番目のテストは空白のままです。
[start=9]
. 英語へのトグルリンクをクリックします。
image::images/toggle-page2.png[title="Welcome page displays in English, according to toggle selection"]
トグルリンクをクリックすると、`header.jspf` ファイルに実装された `<fmt:setLocale>` タグにより、デフォルトのチェコ語がオーバーライドされます。ブラウザの優先言語はチェコ語のままですが、現在そのページは言語切り替えで利用可能にされた新しい言語で表示されているのを確認してください。
[start=10]
. チェコへのトグルリンクをクリックします。
image::images/toggle-page3.png[title="Welcome page displays in Czech, according to toggle selection"]
ブラウザの優先言語に戻すための言語の切替は期待通り動きました。しかしながら、言語を決定する要因はもはや `Accept-Language` HTTPヘッダーで検出された言語ではなく、`<fmt:setLocale>` タグで指定された言語になっていることに注意してください。
[start=11]
. 続ける前に header.jspf ファイルに追加したテストを削除します。(削除するコードは取り消し線のついたテキストです。)
[source,html]
----
<body>
*[.line-through]#<%-- Language tests --%>#
[.line-through]#<p style="text-align: left;"><strong>tests:</strong>#
[.line-through]#<br>#
[.line-through]#<code>\${pageContext.request.locale.language}</code>: ${pageContext.request.locale.language}#
[.line-through]#<br>#
[.line-through]#<code>\${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}</code>: ${sessionScope['javax.servlet.jsp.jstl.fmt.locale.session']}#
[.line-through]#</p>#*
<div id="main">
----
[[keepTrack]]
=== アプリケーションが元のページビューの経過を把握できるようにする
Affable Bean スタッフと合意した<<impDeets,実装の詳細>>の一つは、 言語を変更するために言語切り替えが使用されたとき、ユーザーは同じページビューに残っていることでした。現在の実装では、言語切り替えがクリックされた時はいつでもユーザは welcome ページに返されます。よりユーザーに優しいアプローチは、アプリケーションにリクエストがあったページビューを追跡できる手段を提供し、言語切り替えリンクがクリックされた時、クリックしたページビューへリクエストを送信できるようにすることです。
我々は、各ページビューにセッションスコープ `view` 属性を設定することによってこれを達成することができます。そして、この属性を `ControllerServlet` の中で参照して、リクエストを送信するページを判別します。とはいえ、確認ページの言語切り替えの取扱いについて考慮すべき課題がいくつかあります。これらは以下の7-11で説明され、取扱いされています。
`AffableBean` プロジェクトの link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot9.zip[+スナップショット9+] でこの演習を始めます。このスナップショットには、すべてのページビュー用の英語とチェコの完成版リソースバンドルが含まれています。すべてのページビューはテキストを使いリソースバンドルから変更されています。そして、言語切替は、チュートリアルのこの点に対応した状態になっています。
1. link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot9.zip[+スナップショット9+] を IDE に開きます。プロジェクトを開く( image::images/open-project-btn.png[] )ボタンをクリックして、ウィザードを使用し、プロジェクトをダウンロードしたコンピュータの場所を指定します。
[start=2]
. プロジェクトを実行 ( image::images/run-project-btn.png[] ) ボタンをクリックしてプロジェクトを実行します。サイトをナビゲートして、任意のページビューから言語切り替えをクリックしたときにアプリケーションの welcome ページに返されることに注意してください。
プロジェクトを実行してエラーが表示される場合、セットアップ手順を再度見て下さい。データベースを準備する方法、IDE GlassFish MySQL 間の接続を確立する方法がそこに載っています。
[start=3]
. link:http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/c/set.html[+`<c:set>`+] タグを使用して、各ページビューのセッションスコープ `view` 属性を設定します。各エディタで各ページビューを開き、各ファイルの先頭に次のコードを追加します。
==== index.jsp
[source,java]
----
<%-- Set session-scoped variable to track the view user is coming from.
This is used by the language mechanism in the Controller so that
users view the same page when switching between English and Czech. --%>
<c:set var='view' value='/index' scope='session' />
----
==== category.jsp
[source,java]
----
<%-- Set session-scoped variable to track the view user is coming from.
This is used by the language mechanism in the Controller so that
users view the same page when switching between English and Czech. --%>
<c:set var='view' value='/category' scope='session' />
----
==== cart.jsp
[source,java]
----
<%-- Set session-scoped variable to track the view user is coming from.
This is used by the language mechanism in the Controller so that
users view the same page when switching between English and Czech. --%>
<c:set var='view' value='/cart' scope='session' />
----
==== checkout.jsp
[source,java]
----
<%-- Set session-scoped variable to track the view user is coming from.
This is used by the language mechanism in the Controller so that
users view the same page when switching between English and Czech. --%>
<c:set var='view' value='/checkout' scope='session' />
----
顧客と合意した <<impDeets,実装の詳細>> に基づき、我々は確認ページのビューでは言語切り替えを提供する必要はありません。使いやすさの観点から、チェックアウトする前に、ユーザーはすでに彼または彼女の好みの言語を選択しているでしょう。実装の観点から、注文を正常に完了するために我々はユーザセッションを破棄したことを思い出してください。(link:manage-sessions.html[+セッション管理+]の最後の段落に戻り参照してください。そこには、メソッドを`invalidate`(無効)にして明示的にユーザーセッションを終了する方法について説明してあります。)。Affable Bean スタッフが、お客様はバイリンガルの注文を表示することができるよう強く主張した場合には、次のシナリオをよく考える必要があります。確認ページを表示する時にユーザのセッションを破棄するかどうかに依存して検討する必要があります:
1. *セッションが破棄される:* 確認ページの `chooseLanguage` リクエストが適切なorder(注文)を参照していることを保障するための追加措置を講じる必要があるかどうか、そして顧客に敏感な詳細情報を安全な方法で表示するための追加措置を講じる必要があるかどうか。
[start=2]
. *セッションが保持される:* ユーザが誤って自分のショッピングカートでダブル注文をしてしてしまう危険性や、また不必要となったユーザーのセッションを終了しないためにサーバーに不必要な負荷をかけてよいか。
[start=4]
. `ControllerServlet` をエディタで開きます。(既に開いている場合、Ctrl-Tab を押し、そのファイルを選択します)。開いたファイルで、`chooseLanguage` リクエストを処理する `doGet` メソッドの部分を探します( 126行)。
注意。現在、chooseLanguage リクエストは index.jsp ウェルカムページに転送されます。
[source,java]
----
// if user switches language
} else if (userPath.equals("/chooseLanguage")) {
// get language choice
String language = request.getParameter("language");
// place in session scope
session.setAttribute("language", language);
*// forward request to welcome page
try {
request.getRequestDispatcher("/index.jsp").forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
return;*
}
----
[start=5]
. `view` セッション属性を使用して、リクエストを転送し元のページビューに戻ります。次の変更をします。(太字の部分)。
[source,java]
----
// if user switches language
} else if (userPath.equals("/chooseLanguage")) {
// get language choice
String language = request.getParameter("language");
// place in request scope
request.setAttribute("language", language);
*String userView = (String) session.getAttribute("view");
if ((userView != null) &amp;&amp;
(!userView.equals("/index"))) { // index.jsp exists outside 'view' folder
// so must be forwarded separately
userPath = userView;
} else {
// if previous view is index or cannot be determined, send user to welcome page*
try {
request.getRequestDispatcher("/index.jsp").forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
return;
*}*
}
----
上記の実装では、`view` 属性の値を引き出し、そのビューに提供します:
* 識別することができますか(つまり、値が null でない) can be identified (i.e., the value is not null),
* ウェルカムページから始まっていない( `index.jsp` 他のページビューのように同じ場所に存在しないため、リクエストを転送する `doGet` メソッドの方法を使用して解決することができません)。
[indent]#...あなたは それを `doGet`メソッドの `userPath` 変数に設定し、メソッドにある `RequestDispatcher` を使い、リクエストを転送します:#
[source,java]
----
// use RequestDispatcher to forward request internally
String url = "/WEB-INF/view" + userPath + ".jsp";
try {
request.getRequestDispatcher(url).forward(request, response);
} catch (Exception ex) {
ex.printStackTrace();
}
----
[start=6]
. プロジェクトを実行image::images/run-project-btn.png[] )し、ブラウザでそれをテストします。あなたが、カテゴリ、カートやチェックアウトのページに移動する時、言語切り替えを使用して言語を切り替えてみます。これを行うと、今や、あなたは同じページビュー内にとどまっています。
[start=7]
. ブラウザで、注文を完了し、アプリケーションはあなたを確認ページに転送します。確認ページから言語切り替えをクリックすると、あなたはウェブサイトのウェルカムページに戻らされることに注意します。
実装面では、あなたはこのことを十分に考慮する必要があります。しかし、Affable Beanスタッフがこのページビューから言語切り替えを明示的に削除するように求めています。これを実現する一つの方法は、リクエストの_servlet path_ が「'`/confirmation`'」を含んでいるかどうかを見つけ出すテストを実行することです。
エディタで `header.jspf` ファイルに切り替えます。以下のテストで言語切り替えを囲みます。あなたは、JSTLの機能(つまり、link:http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/fn/tld-summary.html[+`fn`+] )ライブラリを使い文字列操作を実行します。
[source,html]
----
<div class="headerWidget">
*<%-- If servlet path contains '/confirmation', do not display language toggle --%>
<c:if test="${!fn:contains(pageContext.request.servletPath,'/confirmation')}">*
<%-- language selection widget --%>
<c:choose>
...
</c:choose>
*</c:if>*
</div>
----
上記のコードスニペットを調べて、次の点に注意してください:
* サーブレットのパスは link:http://download.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getServletPath%28%29[+`getServletPath`+] メソッドを使い `HttpServletRequest` からアクセスすることができます。我々は `RequestDispatcher` を使用して、リクエストを確認ページ( `ControllerServlet`、行158 )に転送するので、サーブレットのパスは次のようになります:
[source,java]
----
/WEB-INF/view/confirmation.jsp
----
* `pageContext.request.servletPath` EL 式を使用することは、サーブレットから`request.getServletPath()` ()を呼び出すことに相当します。
* link:http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/jstl/1.1/docs/tlddocs/fn/contains.fn.html[+`fn:contains()`+]関数で、あなたは入力文字列に指定された従属文字列が含まれているかどうかテストすることができます。
* `fn` タグライブラリは、すでにスナップショット 9 `header.jspf` ファイルの先頭で宣言されています:
[source,java]
----
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
----
[start=8]
. プロジェクトを再度実行し、確認ページにステップ実行します。そのページにはもはや言語切替えが表示されていないことに注意してください。
image::images/confirmation-page.png[title="Language toggle no longer displays in confirmation page"]
[start=9]
. ブラウザで、言語切り替えを使用しその方法に沿ってもう一度言語を切り替えて、確認ページまでステップ実行します。注意して下さい。あなたが注文を完了するときに、確認ページが誤って最初に表示される言語に戻り切り替わります。あなたは正しく原因を特定することにします:正常に注文が完了したため、 `ControllerServlet` はユーザーセッションを破壊します。その結果として、`<fmt:setLocale>` タグを使用して設定されたセッションスコープのロケールが失われてしまうからです。
この問題を解決するには、`ControllerServlet` を開き、ユーザーセッションを破壊するために使用する `invalidate()` メソッドを検索します。(だいたい 259行目)。
)エディタのクイック検索機能を使います:Ctrl-FMacの場合 ⌘-F)を押し「`invalidate`」を入力します。
[start=10]
. ユーザセッションを破壊する前に、セッションスコープのロケールの値を抽出するコードを追加します。セッションが破棄された後に、リクエストスコープ `language` 属性にロケール値を再セットします。(変更は太字です。)
[source,java]
----
// if order processed successfully send user to confirmation page
if (orderId != 0) {
*// in case language was set using toggle, get language choice before destroying session
Locale locale = (Locale) session.getAttribute("javax.servlet.jsp.jstl.fmt.locale.session");
String language = "";
if (locale != null) {
language = (String) locale.getLanguage();
}*
// dissociate shopping cart from session
cart = null;
// end session
session.invalidate();
*if (!language.isEmpty()) { // if user changed language using the toggle,
// reset the language attribute - otherwise
request.setAttribute("language", language); // language will be switched on confirmation page!
}*
// get order details
Map orderMap = orderManager.getOrderDetails(orderId);
...
userPath = "/confirmation";
}
----
[start=11]
. プロジェクトを再び実行し、言語切り替えを使用する方法に従ってもう一度言語を切り替えて、確認ページまでステップ実行してください。あなたが注文を完了した時に、確認ページがあなたが選択した言語で今度は表示されることに注意してください。
今あなたは、顧客仕様に応じた `AffableBean` アプリケーションの中に言語サポートを正常に統合しました。あなたはページビューからすべてのテキストを取り除き、それをリソースバンドルの中に配置しました。あなたは、JSTL `fmt` タグライブラリを、ユーザの好みの言語に基づいたリソースバンドルのコンテンツを使うように適用しました。あなたはまた、言語切り替えを実装し、ユーザーが英語とチェコ語を切り替えることができるようにしました。そして、ブラウザの既定の言語選択にオーバーライドしました。以下をダウンロードして調べて下さい。link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252Fecommerce%252FAffableBean_snapshot10.zip[+スナップショット10+] とこの単元の最終プロジェクトの状態での作業とを比較してください。
link:/about/contact_form.html?to=3&subject=Feedback: NetBeans E-commerce Tutorial - Adding Language Support[+ご意見をお寄せ下さい+]
[[seeAlso]]
== 関連参照
=== NetBeans リソース
* link:../javaee-intro.html[+Java EE 技術入門+]
* link:../javaee-gettingstarted.html[+Java EE 6 アプリケーション入門 +]
* link:https://netbeans.org/projects/www/downloads/download/shortcuts.pdf[+キーボードショートカットとコードテンプレートカード+]
* link:../../../trails/java-ee.html[+Java EE Java Web 学習の小道+]
=== 外部リソース
* link:http://download.oracle.com/docs/cd/E17409_01/javase/tutorial/i18n/index.html[+Java チュートリアル:国際化+]
* link:http://download.oracle.com/docs/cd/E17477_01/javaee/5/tutorial/doc/bnaxu.html[+Java EE 5 チュートリアル:ウェッブアプリケーションの国際化とローカル化+]
* link:http://java.sun.com/developer/technicalArticles/Intl/MultilingualJSP/index.html[+JavaServer Pagesテクノロジーを使用した多言語 Web アプリケーションの開発+]
* link:http://java.sun.com/developer/technicalArticles/J2SE/locale/[+国際化:Java プラットフォームのロケールを理解する+]
* link:http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/[+Java の国際化:リソースバンドルで現地化+]
* link:http://www.ibm.com/developerworks/java/library/j-jstl0415/[+JSTL 読本、第3回:プレゼンテーションが全て+]
* link:http://java.sun.com/javase/technologies/core/basic/intl/[+Java の国際化+] [技術ホームページ]
* link:http://en.wikipedia.org/wiki/Internationalization_and_localization[+国際化とローカリゼーション+] [Wikipedia]
* link:http://www.loc.gov/standards/iso639-2/php/code_list.php[+ISO 639-2 言語コードリスト+] [Library of Congress]
* link:http://www.w3.org/International/articlelist#language[+W3C 国際化活動:論文、ベストプラクティスとチュートリアル:言語+]
* link:http://jquery.com/[+jQuery+]