Web应用实现国际化(i18n),主要包括两个方面
一、页面(jsp)静态信息的国际化
二、动态消息的国际化
在开始Struts国际化之前,我们先来看一下java如何实现国际化
主要步骤:
1、创建属性文件(国际化资源文件)
*国际化资源文件是有baseName+Locale构成,如MessagesBundle_en_US.properties
*缺省的国际化资源文件是baseName.properties格式命名,如:MessagesBundle.properties
*关于中文必须转换成unicode,可以采用JAVA_HOME/bin/native2ascii工具转换
命令native2ascii.exe o.properties MessagesBundle_zh_CN.properties
也可以一个一个字符转换
举例:
属性文件示例:
k1=China
k2=Hello,{0}
2、定义Locale对象
*可以获得系统默认local,也可以自定义
*缺省的Locale是有操作系统决定的
*Locale是有语言和国家代码构成
3、创建一个ResourceBundle对象
*ResourceBundle对象用于分离跟本地相关的数据
*如果找不到相应语言或国家代码的属性文件,将使用默认的属性文件(即没有标识语言和国家代码的属性文件:MessagesBundle.properties)
4、从ResourceBundle对象中获取数据,如果有占位符,可以给占位符赋值
示例:
- public class test {
- public static void main(String[] args)
- {
- //获取系统默认locle
- Locale localeDefault=Locale.getDefault();
- System.out.println("Country="+localeDefault.getCountry());
- System.out.println("Language="+localeDefault.getLanguage());
- System.out.println("------------------------");
- //我们通过指定一个语言代码和国家代码来创建一个Locale对象
- Locale localeNew=new Locale("en","US");
- System.out.println("Country="+localeNew.getCountry());
- System.out.println("Language="+localeNew.getLanguage());
- System.out.println("------------------------");
- //读取国际化资源文件
- /**
- * 其创建方式如下:
- 第一个参数,表示要从哪些资源属性文件中(MessagesBundle_XX_XX.properties)获取数据
- 第二个参数,是一个Locale对象,表示要选择哪个资源属性文件
- ResourceBundle对象用于分离跟本地相关的数据
- 如果找不到相应语言或国家代码的属性文件,
- 将使用默认的属性文件(即没有标识语言和国家代码的属性文件:MessagesBundle.properties)
- */
- ResourceBundle myResources =ResourceBundle.getBundle("com.jialin.resource.MessagesBundle", localeDefault);
- //从ResourceBundle对象中获取数据
- System.out.println(myResources.getString("k1"));
- System.out.println(myResources.getString("k2"));
- System.out.println("------------------------");
- //给国际化资源文件中的占位符赋值
- MessageFormat myFormat=new MessageFormat(myResources.getString("k2"));
- System.out.println(myFormat.format(new Object[]{"jialin"}));
- }
- }
Strust如何支持国际化?
(一)页面(jsp)静态信息的国际化
我们以登录这个例子来说明。
通过点击中文或英文,实现登录界面语言信息的改变
主要步骤:
1、创建国际化资源文件
*与上一篇中提到的创建方式一致
属性文件内容
MessagesBoundle_zn_CN.properties
login.form.field.username=\u7528\u6237 ----如果为GBK编码,这里是“用户名”
login.form.field.password=\u5BC6\u7801 “密码”
login.form.button.login=\u767B\u5F55 “登录”
我们看到并非为中文,而是unicode编码。
这是采用JAVA_HOME/bin/native2ascii工具转换的,不然会出现乱码
MessagesBoundle_en_US.properties
login.form.field.username=user name
login.form.field.password=password
login.form.button.login=login
2、需要在struts配置文件中指定资源属性文件的位置和名称,如<message-resources parameter="MessageResources" />
*Parameter=国际化资源文件的basename即可
3、在JSP页面中使用Struts标签库来实现显示,如<bean:message key=“key string”/>来输出文本
*需要引入相应的标签库<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
利用这个原理,我们可以用编程的方式来手工切换整个应用系统的语言
示例:
相关action
- <action path="/changeLanguage" type="com.jialin.ChangeLanguageAction"
- scope="request">
- <forward name="login" path="/index.jsp" />
- </action>
- public class ChangeLanguageAction extends Action {
- @Override
- public ActionForward execute(ActionMapping mapping, ActionForm form,
- HttpServletRequest request, HttpServletResponse response)
- throws Exception {
- String lang = request.getParameter("lang");
- Locale locale = Locale.getDefault();
- if ("zh".equals(lang)) {
- locale = new Locale("zh", "CN");
- }else if ("en".equals(lang)) {
- locale = new Locale("en", "US");
- }
- this.setLocale(request, locale);//将语言信息设置到session中
- return mapping.findForward("login");
- }
- }
登录JSP
- <body>
- <form action="login.do" method="post">
- <bean:message key="login.form.field.username" />
- <input type="text" name="name" />
- <br />
- <bean:message key="login.form.field.password" />
- <input type="password" name="password" />
- <input type="submit" value="<bean:message key="login.form.button.login"/>" />
- </form>
- <a href="changeLanguage.do?lang=zh">中文</a>
- <a href="changeLanguage.do?lang=en">英文</a>
- </body>
页面信息的国际化还可以给我们带来另一个好处:我们可以通过修改国际化资源文件更改页面显示的内容,今天叫登录,明天可以改为开始等等。
(二)动态消息的国际化
对于消息提示,异常信息等这些动态信息,我们如何实现国际化呢?
我们依然用上面的例子,在登录验证中加入国际化
更改MessagesBoundle_zn_CN.properties
errors.header=<UL>
errors.prefix=<font color="red"><LI>
errors.suffix=</LI></font>
errors.footer=</UL>
login.form.field.username=\u7528\u6237
login.form.field.password=\u5BC6\u7801
login.form.button.login=\u767B\u5F55
login.success={0},\u767B\u5F55\u6210\u529F --登录成功
login.user.not.found=\u7528\u6237\u4E0D\u80FD\u627E\u5230\uFF0C\u7528\u6237\u540D\u79F0\=\u3010{0}\u3011 --用户未找到,用户=
login.password.error=\u5BC6\u7801\u9519\u8BEF --密码错误
更改MessagesBoundle_en_US.properties
errors.header=<UL>
errors.prefix=<font color="red"><LI>
errors.suffix=</LI></font>
errors.footer=</UL>
login.form.field.username=user name
login.form.field.password=password
login.form.button.login=login
login.success={0},Login Success
login.user.not.found=user not found,user name=[{0}]
login.password.error=password error
Struts配置文件
- <struts-config>
- <!-- set ActionForm info-->
- <form-beans>
- <form-bean name="userForm" type="com.jialin.UserActionForm" />
- </form-beans>
- <global-forwards>
- <forward name="login" path="/index.jsp" />
- <forward name="success" path="/LoginSuccess.jsp" />
- <forward name="fail" path="/LoginFail.jsp" />
- </global-forwards>
- <action-mappings>
- <!-- Set path,action,actionform,scope,forward info -->
- <action path="/login" type="com.jialin.LoginAction" name="userForm"
- scope="request" validate="true" attribute="uf">
- </action>
- <action path="/changeLanguage" type="com.jialin.ChangeLanguageAction"
- scope="request">
- </action>
- </action-mappings>
- <message-resources parameter="com.jialin.resource.MessagesBoundle"></message-resources>
- </struts-config>
LoginAction
第一步:在这个LoginAction中,我们将根据业务逻辑需要获取国际化消息文本ActionMessage,然后将他保存起来到ActionMessages里
第二步:保存这个ActionMessages,用于传递
首先我们要判断要传递的消息是普通消息还是错误消息?
*普通消息:即普通的消息文本
*错误消息:即异常消息文本
本质上,这两种消息没有什么区别,都是消息文本,但是如果一个页面同时需要显示普通的消息文本和错误消息文本的时候,就需要进行区分了,比如不同类型的消息文本可能要用不同的样式来显示
- /**
- * 登录action
- * @author jialin
- *作用:取得表单数据,调用model层业务逻辑,返回转向信息
- */
- public class LoginAction extends Action {
- @Override
- public ActionForward execute(ActionMapping mapping, ActionForm form,
- HttpServletRequest request, HttpServletResponse response)
- throws Exception {
- UserActionForm userForm=(UserActionForm)form;
- String userName=userForm.getName();
- int password=userForm.getPassword(); //这里不用我们手动强转类型了。
- UserManage userManage=new UserManage();
- User user=new User();
- user.setName(userName);
- user.setPassword(password);
- ActionMessages messages = new ActionMessages();
- try {
- userManage.ValidateUser(user);
- //创建国际化消息文本
- ActionMessage message=new ActionMessage("login.success", userName);
- messages.add("login_message_1",message);
- //传递国际化消息,普通消息
- this.saveMessages(request, messages);
- return mapping.findForward("success");
- } catch (UserNotFoundException e) {
- //创建国际化消息文本
- ActionMessage message=new ActionMessage("login.user.not.found", userName);
- messages.add("login_error_1",message);
- //传递国际化消息,异常消息
- this.saveErrors(request, messages);
- }catch (PasswordErrorException e) {
- //创建国际化消息文本
- ActionMessage message=new ActionMessage("login.password.error", userName);
- messages.add("login_error_2",message);
- //传递国际化消息,异常消息
- this.saveErrors(request, messages);
- }
- return mapping.findForward("fail");
- }
- }
UserManage
- /**
- * MODEL层业务逻辑
- *
- * @author jialin 判断用户是否合法
- */
- public class UserManage {
- public void ValidateUser(User user) {
- // 判断用户名密码是否正确
- if (!"jialin".equals(user.getName())) {
- //"用户不存在!用户名为:" + user.getName()"会被Struts用于填充占位符
- throw new UserNotFoundException("用户不存在!用户名为:" + user.getName());
- } else if (user.getPassword() != 123456) {
- //"密码错误“会被Struts用于填充占位符
- throw new PasswordErrorException("密码错误");
- }
- }
- }
自定义异常类PasswordErrorException,UserNotFoundException略
登录失败jsp
- <body>
- <font color="red"> <html:messages id="msg"
- property="login_error_1">
- <bean:write name="msg" />
- </html:messages> </font>
- <font color="blue"> <html:messages id="msg"
- property="login_error_2">
- <bean:write name="msg" />
- </html:messages> </font>
- </body>
别忘记引入taglib
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
也可以用 <html:errors />代替<font color="red"> <html:messages id="msg"property="login_error_1"><bean:write name="msg" /></html:messages> </font><font color="blue"> <html:messages id="msg"property="login_error_2"><bean:write name="msg" /></html:messages> </font>显示异常信息
errors.header=<UL>
errors.prefix=<LI>
errors.suffix=</LI>
errors.footer=</UL>
登录成功jsp
- <body>
- <html:messages id="msg" message="true">
- <bean:write name="msg" />
- </html:messages>
- </body>