所谓的i18n问题指的是(软件的)国际化问题,简单来讲就是使我们的软件可以让世界使用任何语言的人们都能使用,软件自身会根据语言环境的不同进行自动配置,如果你是中文环境那界面以中文显示,如果是英文环境就以英文显示。在i18n问题的解决中,国际化资源文件是不可或缺的,程序正是通过对资源文件的读取来决定究竟以何种界面显示。说到这里如果你认为国际化资源文件仅仅能够解决不同语言版本的显示问题那你就错了,通过对国际化资源文件进行配置我们同样可以实现消息的动态创建和显示。下面我们就来通过实例详细讲解struts如何解决i18n问题。

首先来简单了解国际化资源文件。国际化资源文件是由basename + local+.properties构成的,local指的是语言环境,缺省的local是由操作系统决定的,local由语言和国家代码组成,basename为MessagesBundle,以中文为例,其资源文件名称为:MessagesBundle_zh_CN.properties,缺省的国际化资源文件名称为MessagesBundle.properties。在该文件中,存储方式为key-value形式,所有的key均对应一个value值,程序通过读取该文件中的key值确定应显示的文本。下面通过实例来讲解用struts如何应用资源文件解决i18n问题。

1.  struts的国际化配置。在struts-config.xml文件中加入<message-resourcesparameter="MessageResources"/>。注意parameter的值为国际化资源文件所在的路径,如果国际化资源文件位于src下一个名为resources的文件夹下,则此处parameter的值应为“resources.MessageResources”。

  1. <?xml version="1.0" encoding="ISO-8859-1" ?>
  2.  
  3. <!DOCTYPE struts-config PUBLIC
  4. "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
  5. "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
  6.  
  7. <struts-config>
  8. <form-beans>
  9. <form-bean name="loginForm" type="com.bjpowernode.struts.LoginActionForm"/>
  10. </form-beans>
  11.  
  12. <action-mappings>
  13. <action path="/login"
  14. type="com.bjpowernode.struts.LoginAction"
  15. name="loginForm"
  16. scope="request"
  17. >
  18. <forward name="success" path="/login_success.jsp"/>
  19. <forward name="error" path="/login.jsp"/>
  20. </action>
  21.  
  22. <action path="/changLang"
  23. type="com.bjpowernode.struts.ChangeLanguageAction"
  24. >
  25. <forward name="index" path="/index.jsp"></forward>
  26. </action>
  27. </action-mappings>
  28.  
  29. <message-resources parameter="resources.MessageResources"/>
  30. </struts-config>

2.  提供国际化资源文件。在本例中我们提供三个国际化资源文件,分别为:中文的国际化资源文件MessageResources_zh_CN.properties,英文的国际化资源文件MessageResources_en_US.properties以及缺省的国际化资源文件:MessageResources.properties。注意在中文的国际化文件中,需要把所有的中文转换成unicode编码格式。

3.利用struts默认将locale放到session中的特性,我们可以完成语言的自动切换。

  1. package com.bjpowernode.struts;
  2.  
  3. import java.util.Locale;
  4.  
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7.  
  8. import org.apache.struts.Globals;
  9. import org.apache.struts.action.Action;
  10. import org.apache.struts.action.ActionForm;
  11. import org.apache.struts.action.ActionForward;
  12. import org.apache.struts.action.ActionMapping;
  13.  
  14. public class ChangeLanguageAction extends Action {
  15.  
  16. @Override
  17. public ActionForward execute(ActionMapping mapping, ActionForm form,
  18. HttpServletRequest request, HttpServletResponse response)
  19. throws Exception {
  20. //取得客户端传过来的参数
  21. String lang = request.getParameter("lang");
  22.  
  23. //取得session中默认的locale
  24. Locale locale = Locale.getDefault();
  25.  
  26. //如果传过来的参数为“zh”将locale设为中文,如果参数为“en”则将locale设为英文
  27. if("zh".equals(lang)){
  28. locale = new Locale("zh","CN");
  29. }else if("en".equals(lang)){
  30. locale = new Locale("en", "US");
  31. }
  32. //将locale设置到session中
  33. //request.getSession().setAttribute(Globals.LOCALE_KEY, locale);
  34. this.setLocale(request, locale);
  35. return mapping.findForward("index");
  36. }
  37. }

4.上文中我们已经提过国际化资源文件的作用并不仅仅在于语言环境的转变,他还支持页面的个性化设计以及动态消息的创建。下面我们提供一个英文的资源文件,并以此文件为例介绍动态消息的创建。

4.1  英文国际化资源文件:

  1. errors.header=<UL>
  2. errors.prefix=<font color="blue"><LI>
  3. errors.suffix=</LI></font>
  4. errors.footer=</UL>
  5. login.form.field.username=User Name
  6. login.form.field.password=Password
  7. login.form.button.login=Login
  8. login.success={0},Login Success
  9. login.user.not.found=User Not Found,UserName\=[{0}]
  10. login.password.error=Password Error

4.2  创建动态消息。动态消息的创建分为三个步骤,分别是         创建国际化消息文本,传递国际化消息文本,显示国际化消息文本。在上面的资源文件按中我们可以看到占位符的存在,占位符的存在就给我们动态的创建信息提供了可能,下面看我们是如何通过填充占位符创建动态信息的。

  1. package com.bjpowernode.struts;
  2.  
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5.  
  6. import org.apache.struts.action.Action;
  7. import org.apache.struts.action.ActionForm;
  8. import org.apache.struts.action.ActionForward;
  9. import org.apache.struts.action.ActionMapping;
  10. import org.apache.struts.action.ActionMessage;
  11. import org.apache.struts.action.ActionMessages;
  12.  
  13. public class LoginAction extends Action {
  14.  
  15. @Override
  16. public ActionForward execute(ActionMapping mapping, ActionForm form,
  17. HttpServletRequest request, HttpServletResponse response)
  18. throws Exception {
  19.  
  20. LoginActionForm laf = (LoginActionForm)form;
  21. String username = laf.getUsername();
  22. String password = laf.getPassword();
  23.  
  24. UserManager userManager = new UserManager();
  25. ActionMessages messages = new ActionMessages();
  26. try{
  27. userManager.login(username, password);
  28. //创建国际化消息文本
  29.  
  30. //ActionMessage message = new ActionMessage("login.success",new Object[]{username});
  31. ActionMessage message = new ActionMessage("login.success",username);
  32. messages.add("login_success_1",message);
  33.  
  34. ActionMessage message1 = new ActionMessage("login.success",username);
  35. messages.add("login_success_2",message1);
  36.  
  37. //传递国际化消息
  38. this.saveMessages(request, messages);
  39. return mapping.findForward("success");
  40. }catch(UserNotFoundException e){
  41. e.printStackTrace();
  42. //创建国际化消息文本
  43. ActionMessage error = new ActionMessage("login.user.not.found",username);
  44. messages.add("error_1",error);
  45.  
  46. //传递国际化消息
  47. this.saveErrors(request, messages);
  48.  
  49. }catch(PasswordErrorException e){
  50. e.printStackTrace();
  51. //创建国际化消息文本
  52. ActionMessage error = new ActionMessage("login.password.error");
  53. messages.add("error_2",error);
  54.  
  55. //传递国际化消息
  56. this.saveErrors(request, messages);
  57. }
  58. return mapping.findForward("error");
  59. }
  60.  
  61. }

请注意上面代码中的这条语句:ActionMessagemessage = new ActionMessage("login.success",username);,该语句的作用就在于填充国际化资源文件中的占位符,通过这种方式我们可以动态的创建消息。

5. 在jsp中采用<bean:message>读取国际化消息文本(本例中以登录成功后的页面为例)。

  1. <%@ page language="java" contentType="text/html; charset=GB18030"
  2. pageEncoding="GB18030"%>
  3. <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
  4. <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  6. <html>
  7. <head>
  8. <meta http-equiv="Content-Type" content="text/html; charset=GB18030">
  9. <title>Insert title here</title>
  10. </head>
  11. <body>
  12. <html:messages id="msg" message="true" >
  13. <bean:write name="msg"/>
  14. </html:messages>
  15. </body>
  16. </html>

在该jsp中我们采用的是html:messages标签来读取信息的,在这里需要注意的一点是,这个标签既可以读取message key又可以读取error key,而html:error标签只可以读取error key。根据这一点我们可以决定在错误处理页面和成功页面具体使用哪种标签进行读取。另外使用jstl标签同样可以读取国际化资源文件中的消息,再引入jstl格式化标签库后,使用<html:errors>标签可以读取错误信息,使用<fmt:message>标签可以读取消息。

Struts完美解决i18n问题的更多相关文章

  1. 76. Spring Boot完美解决(406)Could not find acceptable representation原因及解决方法

    [原创文章]        使用Spring Boot的Web项目,处理/login请求的控制器方法(该方法会返回JSON格式的数据).此时如果访问localhost:8080/login.html, ...

  2. 完美解决,浏览器下拉显示网址问题 | 完美解决,使用原生 scroll 写下拉刷新

    在 web 开发过程中我们经常遇到,不想让用户下拉看到我的地址,也有时候在 div 中没有惯性滚动,就此也出了 iScroll 这种关于滚动条的框架,但是就为了一个体验去使用一个框架好像又不值得,今天 ...

  3. 完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法

    完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法   HTML5的语义化标签以及属性,可以让开发者非常方便地实现清晰的web页面布局,加上CSS3的效果渲染,快速建立丰富灵活的web页 ...

  4. 完美解决 Linux 下 Sublime Text 中文输入

    首先,我参考了好几篇文章,都是蛮不错的,先列出来: sublime-text-imfix:首先推荐这个方法,最简单,但是在我的系统上有些问题.可用这个的强烈推荐用这个 完美解决 Linux 下 Sub ...

  5. Linux安装软件时缺少依赖包的简单较完美解决方法!

    大家在linux下源码安装时,有木有经常碰到缺少这个包那个包的,然后不知所措?看到最近有几个筒子安装thrift,安装python因缺少依赖包而进行不下去了.我用的是红帽,装系统的时候习惯把所有的有的 ...

  6. MacBook Pro/Air 下使用 linux ubuntu 系统 波浪号“~”变成其他 符号 的完美解决办法

    打开终端,输入: sudo su - > /sys/module/hid_apple/parameters/iso_layout sudo su -需要root权限,所以使用前请注意已下载roo ...

  7. VC++ 实现VC程序启动时最小化到任务栏(完美解决闪烁问题)

    之前写的一个VC应用程序,是程序启动时就直接出现在任务栏, 窗体不出现,等用户点击任务栏图标再出现窗口.和一些防火墙什么的软件类似. 这种效果实现并不是很困难的,硬是找不到最好的.为什么呢? 首先,在 ...

  8. C# DataGridView控件清空数据完美解决方法

    C# DataGridView控件绑定数据后清空数据在清除DataGridview的数据时: 1.DataSource为NULL(DataGridView.DataSource= null;)这样会将 ...

  9. 完美解决AutoCAD2012,AutoCAD2013本身电脑里有NET4.0或以上版本却装不上的问题

    适用情况:电脑里本身有NET4.0或4.5版本,并且正确安装.或本身你就装有AutoCAD2013或AutoCAD2012要装AutoCAD2012或AutoCAD2013却装不上的情况 如图1所示. ...

随机推荐

  1. Redis学习篇(六)之ZSet类型及其操作

    ZADD 作用: 将元素及其分数添加到集合中 语法: ZADD key score membre [score member] 当集合元素已经存在时,再次添加会更新其分数 当score是 +inf 时 ...

  2. android studio 安卓工作室 汉化完整版

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 汉化包 百度云盘 下载地址:https://pan.baidu.com/s/1pLjwy ...

  3. 初涉springboot(二)

    概述 1.环境说明 2.HelloWorld项目细节   3.小结 一. 关于环境补充 在上一篇的HellWorld项目中,我们构建SpringBoot项目,采用的是jdk1.8版本,springbo ...

  4. Shell脚本:“syntax error:unexpected end of file”

    这种错误只能说是坑,如果没有见到过,很可能就要摔里头.解决问题是重要的,但弄明白问题的来源,往往更为重要. 所以要先扯一下,换行和回车的历史遗留问题. 在计算机出现之前,有个玩意叫电传打字机.每秒钟可 ...

  5. 【转载】Unicode 编码表

    转载备忘:Unicode 编码表 具体请移步: http://www.cnblogs.com/chenwenbiao/archive/2011/08/17/2142718.html

  6. ThinkPHP -- 去除URL中的index.php

    原路径是 http://localhost/test/index.php/index/add 想获得的地址是 http://localhost/test/index/add 那么如何去掉index.p ...

  7. python开发_python代码风格(coding style)

    我们要做python开发,我想python中的代码风格我们有必要了解一下 这样对我们自己和他们所编写的代码都有好处的. 下面是8点重要代码风格注意事项: ONE : Use 4-space inden ...

  8. [转]JSP或servlet中(以及上传下载文件)中文乱码或不显示的解决方案

    时间 2014-04-14 14:33:44  CSDN博客 原文  http://blog.csdn.net/xby1993/article/details/23677375 主题 ServletJ ...

  9. BZOJ 4517: [Sdoi2016]排列计数 错排公式

    4517: [Sdoi2016]排列计数 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4517 Description 求有多少种长度为 ...

  10. 机器学习中的 precision、recall、accuracy、F1 Score

    1. 四个概念定义:TP.FP.TN.FN 先看四个概念定义: - TP,True Positive - FP,False Positive - TN,True Negative - FN,False ...