跳至内容 Java Solaris 社区 Sun 商店 加入 SDN 我的个人档案 加入的益处
 
创建国际化应用程序
2006 年 5 月 [修订号:V2.1-1]  
本教程介绍了如何使用 Sun Java Studio Creator 应用程序开发工具(或 IDE)来创建国际化 Web 应用程序。本教程描述的应用程序在运行时允许客户端浏览器设置应用程序的语言环境和字符编码。当您的应用程序必须支持多语言、同一语言的不同编码或旧式编码时,此功能特别有用。在可供选择的四种语言环境和三种字符编码中,应用程序会对用户的选择作出响应。当用户选择了一种语言环境和编码后,应用服务器将发送以该编码显示的文本,同时接受用户输入的、以同一编码表示的文本。
 
目录
 
设置系统
创建项目
设计用户界面
提供操作方法
创建属性绑定
测试应用程序
[spacer] 此页上的内容适用于 Sun Java Studio Creator 2
 
本教程中使用的示例
 

设置系统

 
在学习本教程之前,请将您的系统设置为显示英语、俄语、日语和简体中文语言。对于英语和俄语,请启用 UTF-8 编码;对于日语,请启用 Shift_JIS 编码;对于简体中文,请启用 GB2312 编码。
 

创建项目

  1. 启动 IDE,并通过选择“文件”>“新建项目”来创建一个新项目。在“新建项目”窗口中,选择 "Web" 类别和“JSF Web 应用程序”项目。

  2. 单击“下一步”,并将项目命名为 HelloBundledWorld。这将打开可视设计器,并显示没有任何内容的 Page1。
 

设计用户界面

 
您将使用网格面板组件来组织用户界面元素,这样可有效地防止运行应用程序时其布局在浏览器和操作系统之间出现差异。网格面板组件在创建国际化应用程序时非常有用 - 当您使用网格面板组件时,页面布局很少会受到因各种语言的字符串长度存在差异而造成的影响。
 
  1. 在“组件面板”>“组件”标签中,选择下表所示的 14 个组件,并将它们拖动到可视设计器的页面上。

    表 1:要放置在页面上的组件
     
    数量    
    组件类型
    ID 属性
    3
    布局 > 网格面板
    gridLarge、gridUpperRight、gridCenterRight
    6
    基本 > 静态文本
    helloText、chosenOption、chosenIndex、chosenLocale、chosenEncoding、youEnteredDisplay
    2
    基本 > 标签
    enterTextLabel、youEnteredLabel
    1
    基本 > 按钮
    submitButton
    1
    基本 > 文本字段
    textEntry
    1
    基本 > 下拉列表     
    localeDropDown
     
    虽然此时组件的位置并不重要,但您还是应该按照如下图所示来组织页面:
     
    图 1:初始页面布局
    图 1:初始页面布局
     
  2. 在可视设计器中,依次选择每个组件,并将其 id 属性更改为表 1 第 3 列中显示的值。请忽略 id 属性的原始缺省值。

  3. 依次选择每个网格面板组件,然后在“属性”窗口中,将每个组件的 column 属性更改为 2,并将其 rules 属性更改为 all。显示标线将有助于您调整布局。

    现在将按最终的配置来排列组件。最简单的方法是:在“概要”窗口中拖动这些组件的名称。

  4. 在“概要”窗口中,展开 "page1" > "html1" > "body1" > "form1" 节点。拖动组件名称以对其进行组织,如下图所示。
     
    图 2:在“概要”窗口中组织页面布局
    图 2:在“概要”窗口中组织页面布局
     
    现在,可视设计器中的页面应如下图所示。
     
    图 3:按网格组织的页面布局
    图 3:按网格组织的页面布局
     
  5. 选择每个网格面板组件,并调整其大小使布局更紧凑,如下图所示。调整了每个网格面板后,将其 rules 属性更改为 none,去除标线的显示。
     
    图 4:
调整网格面板的大小
    图 4:调整网格面板的大小
     
  6. 选择“按钮”组件,然后在“属性”窗口中更改以下属性:

    • 外观 > textSubmit

  7. 选择“下拉列表”组件,然后在“属性”窗口中更改以下属性:

    • 高级 > immediate选中
    • 高级 > valueChangeListener#{Page1.localeDropDown_processValueChange}

    选中“高级”> immediate 后,当用户从列表中选择一个新值时,将提交表单。

    现在可以设置绑定的属性文件了,这些文件使得页面上的组件可以显示本地化为不同语言的字符。通过 IDE 的绑定属性功能,您可以为希望应用程序支持的每种语言环境保留一个单独的文件。每个文件都包含一个或多个键-值对。当您的应用程序引用某个键时,客户端浏览器的界面将被替换成该键值所对应的语言界面。
 

提供操作方法

 
现在,让我们来编辑按钮组件的 submit_action() 方法和下拉列表组件的 localeDropDown_processValueChange() 方法。
  1. 在可视设计器显示的 Page1 上,双击 "Submit" 按钮。IDE 将为该按钮组件创建操作方法:打开 Java 编辑器,并将编辑光标放置在该方法中。

  2. 按照以下代码示例来编辑 submitButton_action() 方法:
     
    代码示例 1:submitButton 操作方法
        public String submitButton_action() {        
    	 // Get value of drop-down list and process it
            String str = this.localeDropDown.getValue().toString();
            processLocaleChange(str);
            
            return null;
        }
    
     
  3. 返回到显示该页面的可视设计器中,然后双击“下拉列表”组件。IDE 将为该组件创建一个处理值的变更的方法:打开 Java 编辑器,并将编辑光标放置在该方法中。

  4. 按照以下代码示例编辑 localeDropDown_processValueChange() 方法:
     
    代码示例 2:下拉列表组件的处理值的变更的方法
        public void localeDropDown_processValueChange(ValueChangeEvent event) {
             // Process new drop-down list value
            processLocaleChange((String)event.getNewValue());
        }
    
     
添加 processLocaleChange() 方法
 
您刚才编辑的两个方法都需要调用 processLocaleChange() 方法。现在我们来编写该方法。
  1. 在 Java 编辑器显示的 Page1 上,滚动到 Page1 类的开头,然后添加三行代码以定义变量 indexencodingslocales。该类的前四行应该与以下代码示例中所示的代码类似。
     
    代码示例 3:初始化 index、encodings 和 locales 变量
    public class Page1 extends AbstractPageBean {
        private int index =-1;
        String[] encodings = {"UTF-8", "UTF-8", "Shift_JIS", "GB2312"};
        String[] locales = {"en_US", "ru_RU", "ja_JP", "zh_CN"};
    
     
  2. 滚动到文件的结尾处,然后在最后一个右花括号 (}) 之前插入以下代码样例中的代码。processLocaleChange() 方法用于获取用户在下拉列表中选择的语言和语言环境,确定前两个字符并利用它们来设置用于呈现 JavaServer Faces 组件的语言环境。在 processLocaleChange() 方法后面创建的 String 对象用于存储用户输入的文本。
     
    代码示例 4:processLocaleChange() 方法的代码
        private void processLocaleChange(String str) {
    
            chosenOption.setValue(":::"+str+":::");
            String encString = str;
            
            // Get items from localeDropDown
            Option[] options = (Option[])localeDropDown.getItems();
            String[] items = new String[options.length];
            for (int i=0; i < options.length; i++) {
                items[i] = (String)options[i].getValue();
            }
            
            
            for (index = 0; index < items.length; index++) {
                if (items[index].startsWith(encString))
                    break;
            }
            
            chosenIndex.setValue("# "+index);
            if (index>=0&&index < items.length) {
                String locStr = locales[index];
                Locale locale;
                if (locStr.length()>3)
                    locale = new Locale(locStr.substring(0,2), locStr.substring(3,5));
                else
                    locale = new Locale(locStr.substring(0,2));
                // Set the locale for rendering JSF components...
                FacesContext.getCurrentInstance().getViewRoot().setLocale(locale);
                // Save the encoding to use for this locale...
                getSessionBean1().setSessionEncoding(encodings[index]);
                chosenLocale.setValue(" = "+locStr);
                chosenEncoding.setValue(encodings[index]);
                
            } else {
                index =-1;
            }
        }
         /**
         * Holds value of property capturedText.
         */
        private String capturedText;
        
        /**
         * Getter for property capturedText.
         * @return Value of property capturedText.
         */
        public String getCapturedText() {
            
            return this.capturedText;
        }
        
        /**
         * Setter for property capturedText.
         * @param capturedText New value of property capturedText.
         */
        public void setCapturedText(String capturedText) {
            
            this.capturedText = capturedText;
        }
    
     
  3. 要消除因文件存在未解析的符号而导致的错误,请在 Java 编辑器中单击鼠标右键,然后从上下文菜单中选择“修复导入”。如果因为多个包都含有同一类名而出现一个对话框,请选择包含 com.sun.rave.web.ui.component 的全限定名称,如下图所示。
     
    图 5:为 import 语句选择类名
    图 5:为 import 语句选择类名
 
将属性添加到会话 Bean
 
现在,将属性添加到会话 Bean 以存储下拉列表的值。
  1. 在可视设计器显示的 Page1 上,查看“概要”窗口中的项目内容。右键单击 "SessionBean1" 节点,然后从上下文菜单中选择“添加”>“属性”。将打开“新建属性模式”对话框。

  2. 在“新建属性模式”对话框中,键入 sessionEncoding 作为属性名称,并选择 String 作为类型,如下图所示。
     
    图 6:“新建属性模式”对话框
    图 6:“新建属性模式”对话框
     
  3. 在“概要”窗口中再次右键单击 "SessionBean1" 节点,然后从弹出式菜单中选择“添加”>“属性”。在“新建属性模式”对话框中,键入 dropDownOptionsDescriptions 作为属性名称,并选择 Option[] 作为类型,如下图所示。
     
    图 7:将新属性添加到会话 Bean
    图 7:将新属性添加到会话 Bean
     
将初始化代码添加到会话 Bean
 
现在需要将初始化代码添加到会话 Bean 中,该代码用于定义在下拉列表中向用户显示的选项。
  1. 在“概要”窗口中,右键单击 "SessionBean1" 节点,然后从弹出式菜单中选择“打开”。这将在 Java 编辑器中打开 SessionBean1.java 文件以进行编辑。在 init() 方法中找到以下注释行: 
    // 执行必须在初始化受管组件
    // *之后*完成的应用程序初始化
    // 待做事项 - 在此处添加您自己的初始化代码
    
     
  2. 在注释行下面插入初始化代码,如以下代码样例所示。
     
    代码示例 5:会话 Bean 的初始化代码
            // Perform application initialization that must complete
            // *after* managed components are initialized
            // TODO - add your own initialization code here
            
            // Keep the same locale across requests...
            sessionEncoding = new String("UTF-8");
            
            // Description settings for initializing localeDropDown on Page1
            dropDownOptionsDescriptions = new com.sun.rave.web.ui.model.Option[] {
                new Option("en_US", "English" ),
                new Option("ru_RU ", "Russian " ),
                new Option("ja_JP ", "Japanese " ),
                new Option("zh_CN ", "Chinese")                    
            };
    
     
  3. 要消除因文件存在未解析的符号而导致的错误,请在 Java 编辑器中单击鼠标右键,然后从上下文菜单中选择“修复导入”。如果因为多个包都含有同一类名而出现一个对话框,请选择包含 com.sun.rave.web.ui.component 的全限定名称。下面显示的行将被添加到 import 语句中: 
    import com.sun.rave.web.ui.model.Option;
    
     
    现在 SessionBean.java 文件应当不会显示因存在未解析的符号而导致的错误。
 

创建属性绑定

  1. 在“项目”窗口中,展开 "HelloBundledWorld" >“源包”> "hellobundledworld" 节点。右键单击 "Bundle.properties" 节点,然后从上下文菜单中选择“打开”。将打开属性编辑器。

  2. 单击“新建属性”以打开“新建属性”对话框。输入以下值,然后单击“确定”:

    • 键:hello
    • 值:Hello, whole world!
    • 注释:Greeting

  3. 再次单击“新建属性”以打开“新建属性”对话框。输入以下值,然后单击“确定”:

    • 键:enterSomeText
    • 值:Enter some text:
    • 注释:Text getter function

  4. 最后一次单击“新建属性”以打开“新建属性”对话框。输入以下值,然后单击“确定”:

    • 键:youEntered
    • 值:You entered:
    • 注释:Text user entered

    现在您会在属性编辑器中看到所输入的键和值,如下图所示。当应用程序回复客户端浏览器请求时,这些值将被用作缺省的字符串。
     
    图 8:显示新键和值的属性编辑器
    图 8:显示新键和值的属性编辑器
     
将语言环境添加到属性绑定
 
现在将语言环境添加到属性绑定,并提供可用于其他语言的键值。
  1. 在“项目”窗口中,右键单击 "HelloBundledWorld" >“源包”> "hellobundledworld" > "Bundle.properties" 节点,然后从上下文菜单中选择“添加语言环境”。将打开“新建语言环境”对话框。

  2. 在“新建语言环境”对话框的“预定义的语言环境”列表中向下滚动,然后选择 ru_RU - 俄文/俄罗斯语言环境,如下图所示。单击“确定”。
     
    图 9:显示俄文语言环境的“新建语言环境”对话框
    图 9:显示俄文语言环境的“新建语言环境”对话框
     
  3. 再次右键单击 "Bundle.properties" 并选择“添加语言环境”。在“新建语言环境”对话框中,选择 ja_JP - 日文/日本语言环境,然后单击“确定”。

  4. 最后一次右键单击 "Bundle.properties" 并选择“添加语言环境”。在“新建语言环境”对话框中,选择 zh_CN - 中文/中国语言环境,然后单击“确定”。

    现在属性编辑器应该在新列中显示添加的语言环境,如下图所示。
     
    图 10:显示已添加语言环境的属性编辑器
    图 10:显示已添加语言环境的属性编辑器
     
提供特定于语言的值
 
现在,让我们为每种语言环境中的键提供特定于语言的值。
  1. 在“项目”窗口中,展开 "HelloBundledWorld" >“源包”> "hellobundledworld" > "Bundle.properties" 节点,然后双击 ja_JP - 日文 (日本) 节点。将在文本编辑器中打开该属性文件。

  2. 请按照以下代码样例来编辑文件:
     
    代码示例 6:日文(日本)文本的 ASCII 代码
    # Sample ResourceBundle properties file
    
    #Greeting
    hello=\u4E16\u754C\u3001\u4ECA\u65E5\u306F \!
    
    #Text getter function
    enterSomeText=\u5165\u529B\u3057\u3066\u4E0B\u3055\u3044\uFF1A
    
    #Text user entered
    youEntered=\u3042\u306A\u305F\u306F\u3053\u308C\u3092\u5165\u308C\u307E\u3057\u305F\:
    
     
    您输入的值是要显示的日文字符的字符代码。请保存文件并关闭文本编辑器。

  3. 返回到属性编辑器,并查看日文列中的值。如果系统能够显示日文,则属性编辑器应该如下图所示。
     
    图 11:显示日文字符的属性编辑器
    图 11:显示日文字符的属性编辑器
     
    请注意,您还可以直接在属性编辑器中输入国际字符,而不必在文本编辑器中输入其代码。并且还可以将国际字符复制并粘贴到属性编辑器的值字段中。

  4. 在属性编辑器中或在通过文本编辑器打开的单个属性文件中输入俄文和简体中文字符。属性文件中的 ASCII 文本应该如代码样例 7 和 8 所示,并且属性编辑器应该如图 12 所示。
     
    代码示例 7:俄文(俄罗斯)文本的 ASCII 代码
    #Greeting
    hello=\u0412\u0441\u0435\u043C  \u043F\u0440\u0438\u0432\u0435\u0442  \!
    
    #Text getter function
    enterSomeText=\u0412\u0432\u0435\u0434\u0438\u0442\u0435
    \u043A\u0430\u043A\u043E\u0439-\u043B\u0438\u0431\u043E
    \u0442\u0435\u043A\u0441\u0442\:
    
    #Text user entered
    youEntered=\u0412\u044B \u0432\u0432\u0435\u043B\u0438\:
    
     
    代码示例 8:简体中文文本的 ASCII 代码
    #Greeting
    hello=\u4E16\u754C, \u60A8\u597D\!\u4ECA\u65E5\!
    
    #Text getter function
    enterSomeText=\u8F93\u5165\:
    
    #Text user entered
    youEntered=\u4F60\u9009\u62E9\:
    
     
    图 12:显示国际化文本的属性编辑器
    图 12:显示国际化文本的属性编辑器
     
  5. 请保存并关闭属性编辑器。
 
在 Page1.jsp 中添加标记
 
现在,我们要在 Page1.jsp 文件中添加一个将应用程序定向到资源绑定的标记。
  1. 在可视设计器中查看 Page1。将一个“装入包”组件从组件面板拖动到页面的空白部分。“装入包”组件将在 Page1.jsp 代码中创建 <f:loadBundle ...> 指令。

  2. 在“概要”窗口中,选择 "Page1" > "html1" > "f:loadBundle:messages1" 节点,然后在“属性”窗口中查看其属性,如下图所示。请注意,var 的值是 messages1。您需要利用该值将用户界面中的静态文本组件和标签组件与属性绑定中的字符串绑定。
     
    图 13:查看 


f:loadBundle:messages1 的属性
    图 13:查看 f:loadBundle:messages1 的属性
     
  3. 在“概要”窗口中,选择 "page1" > "html1" > "body1" > "form1" > "gridLarge" > "helloText" 组件,单击鼠标右键,然后从上下文菜单中选择“绑定到数据”。在出现的对话框中,单击“绑定到对象”并输入 #{Page1.helloText}。单击“确定”。

  4. 当 "helloText" 组件在“概要”窗口中处于选定状态时,请在其“属性”窗口中找到 text 属性。为该属性输入以下值:#{messages1.hello}。该值是一个绑定表达式,它在运行时会将组件的显示文本与 hello 键所对应的值进行绑定。

  5. 在“概要”窗口中,选择 "enterTextLabel" 组件。在“属性”窗口中,为其 text 属性输入以下值:#{messages1.enterSomeText}

  6. 在“概要”窗口中,选择 "youEnteredLabel" 组件。在“属性”窗口中,为其 text 属性输入以下值:#{messages1.youEntered}

  7. 在“概要”窗口中,选择 "youEnteredDisplay" 组件,单击鼠标右键,然后从上下文菜单中选择“属性绑定”。在“youEnteredDisplay 的属性绑定”对话框中,选择 text 属性和绑定目标 "Page1" > "capturedText",如下图所示。单击“应用”,然后单击“关闭”。
     
    图 14:绑定 youEnteredDisplay 组件


的 text 属性
    图 14:绑定 youEnteredDisplay 组件的 text 属性
     
  8. 在“概要”窗口中,选择 "textEntry" 组件,单击鼠标右键,然后从上下文菜单中选择“属性绑定”。在“textEntry 的属性绑定”对话框中,再次选择 text 属性和 "Page1" > "capturedText" 目标。单击“应用”,然后单击“关闭”。

  9. 在“概要”窗口中,选择 "page1" > "html1" > "body1" > "form1" > "gridUpperRight" > "localeDropDown" 组件,单击鼠标右键,然后从上下文菜单中选择“属性绑定”。在“localeDropDown 的属性绑定”对话框中,选择 items 属性和 "SessionBean1" > "dropDownOptionsDescriptions" 目标。单击“应用”,然后单击“关闭”。
 
编辑 faces-config.xml 文件
 
现在让我们来编辑 faces-config.xml 文件,以便为应用程序配置支持的语言环境。
  1. 在“文件”窗口中,展开 "HelloBundledWorld" > "web" > "WEB-INF" 节点,然后右键单击 faces-config.xml 节点。从上下文菜单中选择“编辑”,将打开文件进行编辑。

  2. 请按照以下代码样例编辑 <faces-config> 标记。请确保已删除了缺省文件中 <application> 标记周围的注释行。
     
    代码示例 9:在 faces-config.xml 中指定缺省的语言环境和支持的语言环境
    <faces-config>
    
      <application>
        <locale-config>
          <default-locale>en</default-locale>
          <supported-locale>ru</supported-locale>
          <supported-locale>ja</supported-locale>
          <supported-locale>cn</supported-locale>
        </locale-config>
      </application>
    
    </faces-config>
    
     
    请注意:上面的 <supported-locale> 标记仅用来指定语言代码(例如 ja),并不包括语言环境代码(例如 ja_JP)。由于并非所有的浏览器都可以接受语言环境代码,因此这些代码被忽略了。

  3. 请保存文件并关闭编辑器。
 

测试应用程序

 
通过选择“运行”>“运行主项目”来生成并运行应用程序。如果一切正常,将打开浏览器来显示应用程序的英文版本。通过从下拉列表中选择不同的语言,您会在用户界面中看到:原来的英文版本被替换为绑定的属性文件中输入的值。当您在文本字段中输入文本(或复制并粘贴文本,如下图所示)时,在文本字段组件下方的静态文本组件中会回显该文本。
 
图 15:在运行时显示国际文本的应用程序
图 15:在运行时显示国际文本的应用程序
 

小结

 
在本教程中,您首先将系统和浏览器设置为以 UTF-8、Shift_JIS 和 GB2312 编码来显示英语、俄语、日语和简体中文字符,然后使用“基本”组件对页面进行布局。接下来,创建资源绑定,并输入了用四种语言表示的字符串值。最后,将组件的显示属性与资源绑定中的键进行绑定。
 
在运行时,用户可以从下拉列表中选择一种语言。客户端浏览器通过该选择向应用服务器发出请求,即构建一个由所选语言来表示的页面。通过引用绑定的属性文件中的值,服务器将以请求的语言和编码来构建并提供页面。
 
利用属性的绑定资源,样例应用程序会根据用户对四种语言环境和三种字符编码做出的选择而进行响应。在用户选择了一种语言环境和编码后,应用服务器将发送以该编码显示的文本,并接受用户输入的以同一编码表示的文本。
 
允许用户指定语言环境和编码的应用程序将会赢得广泛的用户群,其中包括使用旧式编码或者具有其他特殊需求的用户。
 
另请参见
 
更多的开发者资源
 
有关为开发者提供的更多教程、文章、提示、论坛、更新和专家建议,请访问 Sun Developer Network (SDN) 上的 Java Studio Creator 开发者资源,网址为 http://gceclub.sun.com.cn/prodtech/javatools/jscreator/
 

 
此页的最新修改时间:2006 年 5 月 12 日