所谓的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”。

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd"> <struts-config>
<form-beans>
<form-bean name="loginForm" type="com.bjpowernode.struts.LoginActionForm"/>
</form-beans> <action-mappings>
<action path="/login"
type="com.bjpowernode.struts.LoginAction"
name="loginForm"
scope="request"
>
<forward name="success" path="/login_success.jsp"/>
<forward name="error" path="/login.jsp"/>
</action> <action path="/changLang"
type="com.bjpowernode.struts.ChangeLanguageAction"
>
<forward name="index" path="/index.jsp"></forward>
</action>
</action-mappings> <message-resources parameter="resources.MessageResources"/>
</struts-config>

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

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

package com.bjpowernode.struts;

import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.struts.Globals;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping; public class ChangeLanguageAction extends Action { @Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//取得客户端传过来的参数
String lang = request.getParameter("lang"); //取得session中默认的locale
Locale locale = Locale.getDefault(); //如果传过来的参数为“zh”将locale设为中文,如果参数为“en”则将locale设为英文
if("zh".equals(lang)){
locale = new Locale("zh","CN");
}else if("en".equals(lang)){
locale = new Locale("en", "US");
}
//将locale设置到session中
//request.getSession().setAttribute(Globals.LOCALE_KEY, locale);
this.setLocale(request, locale);
return mapping.findForward("index");
}
}

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

4.1  英文国际化资源文件:

errors.header=<UL>
errors.prefix=<font color="blue"><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,UserName\=[{0}]
login.password.error=Password Error

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

package com.bjpowernode.struts;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages; public class LoginAction extends Action { @Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception { LoginActionForm laf = (LoginActionForm)form;
String username = laf.getUsername();
String password = laf.getPassword(); UserManager userManager = new UserManager();
ActionMessages messages = new ActionMessages();
try{
userManager.login(username, password);
//创建国际化消息文本 //ActionMessage message = new ActionMessage("login.success",new Object[]{username});
ActionMessage message = new ActionMessage("login.success",username);
messages.add("login_success_1",message); ActionMessage message1 = new ActionMessage("login.success",username);
messages.add("login_success_2",message1); //传递国际化消息
this.saveMessages(request, messages);
return mapping.findForward("success");
}catch(UserNotFoundException e){
e.printStackTrace();
//创建国际化消息文本
ActionMessage error = new ActionMessage("login.user.not.found",username);
messages.add("error_1",error); //传递国际化消息
this.saveErrors(request, messages); }catch(PasswordErrorException e){
e.printStackTrace();
//创建国际化消息文本
ActionMessage error = new ActionMessage("login.password.error");
messages.add("error_2",error); //传递国际化消息
this.saveErrors(request, messages);
}
return mapping.findForward("error");
} }

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

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

<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>Insert title here</title>
</head>
<body>
<html:messages id="msg" message="true" >
<bean:write name="msg"/>
</html:messages>
</body>
</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. FastReport.Net使用:[22]地图(Map)控件

    标记有学生地区 1.在报表中放一个地图控件 将地图控件放在标题区即可,其他栏目删除. 2.双击地图控件进行地图添加. 可以再网上下载到地图数据,ESRI shapefile文件,本例中找了个省会城市地 ...

  2. FastReport.Net使用:[2]添加MSSQL数据源一

    如何使用MSSQL表作为数据源 1.点击FastReport设计器中Data->Add Data Source菜单项,打开数据源添加向导. 2.添加新的数据连接. 点击 New connecti ...

  3. 新浪微博API的使用Python

    本文记录了用新浪微博官方Python SDK调用API进行开发的流程. 准备工作 申请成为开发者并创建一个应用: 首先要有一个新浪微博的账号,然后去新浪微博开放平台(http://open.weibo ...

  4. 模拟算法+栈 HDU 1022

    Train Problem I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  5. maven构建jar包

    1.执行可执行的class,代码内需要有入口main方法 2.通过mvn package来构建jar包 3.使用java -jar test.jar来执行jar包 https://www.cnblog ...

  6. ReactNative 调用手机地图(高德、百度)导航 Android

    由于项目需要,鉴于第三方sdk包的体积略大,经过评估论证后,决定采用调起APP以及网页地图的方式来进行导航. 思路: 在需要调用导航的界面通过原生获取当前手机内可用的导航app组装成列表返回到RN待选 ...

  7. TPS61175/TPS55340 3A/5A、40V 电流模式集成 FET 升压 DC/DC 转换器

    集成型5A 40V 宽输入范围升压/单端初级电感转换器(SEPIC) / 反激式(Flyback) 直流到直流稳压器 (Rev. B) 描述 TPS55340 是一款单片非同步开关稳压器,此稳压器带有 ...

  8. Autocomplete TEdit

    http://forum.codecall.net/topic/75946-autocomplete-tedit/ Overview Autocomplete feature really helpf ...

  9. MP2359 1.2A, 24V, 1.4MHz Step-Down Converter in a TSOT23-6

    The MP2359 is a monolithic step-down switch mode converter with a built-in power MOSFET.It achieves ...

  10. uva 1203 - Argus(优先队列)

    option=com_onlinejudge&Itemid=8&page=show_problem&problem=3644" target="_blank ...