1. I18N问题

什么是I18N问题?

在英文中, 国际化(Internationalization)被缩写为I18N, 即只取首尾两个字母, 中间字母为18

问题在哪里?

页面字符串硬编码

异常消息的硬编码

提示信息的硬编码

2. Java如何支持I18N

一个简单的例子

不支持I18N的例子 – NoI18NSample.java

public class NoI18NSample {

/**

* @param args

*/

public static void main(String[] args) {

System.out.println("你好!");

System.out.println("最近过得如何?");

System.out.println("再见!");

}

}

支持I18N的例子

我们需要将硬编码文本转移到外部的资源文件

编写MessagesBundle.properties

sen1=Hello!

sen2=How are you?

sen3=Good bye!

编写MessagesBundle_zh_CN.properties

sen1=你好,{0}

sen2=最近怎么样?

sen3=再见!

编写MessagesBundle_en_US.properties

sen1=Hello!

sen2=How are you?

sen3=Good bye!

编写I18NSample.java

public class I18NSample {

/**

* @param args

*/

public static void main(String[] args) {

Locale currentLocale = new Locale("zh","CN");

ResourceBundle messages = ResourceBundle.getBundle("MessagesBundle",currentLocale);

System.out.println(messages.getString("sen1"));

System.out.println(messages.getString("sen2"));

System.out.println(messages.getString("sen3"));

}

}

运行I18NSample.java

乱码?

因为资源文件必须是Latin-1Unicode编码(如/udddd)的字符

使用native2ascii工具,将中文资源文件进行转换

3. Java支持I18N的编码过程总结

1、创建属性文件(可能要用native2ascii工具转换)

2、定义Locale对象

3、创建一个ResourceBundle对象

ResourceBundle对象用于分离跟本地相关的数据

如果找不到相应语言或国家代码的属性文件,将使用默认的属性文件(即没有标识语言和国家代码的属性文件:MessagesBundle.properties

其创建方式如下:

message = ResourceBundle.getBundle("MessagesBundle", currentLocale);

第一个参数,表示要从哪些资源属性文件中(MessagesBundle_XX.properties)获取数据

第二个参数,是一个Locale对象,表示要选择哪个资源属性文件

4、从ResourceBundle对象中获取数据

4. Locale对象

我们通过指定一个语言代码和国家代码来创建一个Locale对象

国家代码是可选的

语言代码是小写字母;国家代码是大写字母

Locale.getDefault()可以获得系统当前的Locale

Java都支持哪些语言代码和国家代码?

DateFormat.getAvailableLocales()

语言代码标准:http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt

国家代码标准:http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_3166.html

Locale相关的数据:

消息文本(带参数?)

如果消息带参数,需要使用MessageFormat类来进行格式化

比如,将消息资源文件改变:

sen1=Hello,{0}!

MessageFormat mf = new MessageFormat(messages.getString("sen1"));

System.out.println(mf.format(new Object[]{"Jack"}));

日期(时间)

货币(数字)

等等。。。

public class FormatSample {

/**

* @param args

*/

public static void main(String[] args) {

Locale currentLocale = new Locale("zh","CN");

//按照日期的:短、中、长或FULL的形式来显示日期字符串

DateFormat format = DateFormat.getDateInstance(DateFormat.FULL, currentLocale);

Date date = new Date();

System.out.println(format.format(date));

//Numbers

NumberFormat numberFormat = NumberFormat.getNumberInstance(currentLocale);

double d = 287832347.837938;

System.out.println(numberFormat.format(d));

NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(currentLocale);

System.out.println(currencyFormat.format(d));

}

}

5. Struts如何支持I18N

1、需要在struts配置文件中指定资源属性文件的位置和名称,如

<message-resources parameter="MessageResources" />

2、在相应的位置放置相应的文件

3、在JSP页面中使用<bean:message key=key string/>来输出文本,以避免硬编码

以登录页面的国际化作为例子讲解

创建相应的资源属性文件

<bean:message/>标签替换登录页面的硬编码文本

测试(更改网页显示语言,以便测试不同的版本)

6. 关于message-resources 配置中parameter的值

parameter的值,可以指定资源文件的位置和名称

举例:

<message-resources parameter="MessageResources" />

表示在类路径根目录(WEB-INF/classes目录)下有MessageResources_XX_XX.properties文件(注意:国家代码可以省略,跟java中对资源属性文件的处理一样)

<message-resources parameter="resources.application"/>

表示在类路径根目录下,有一个resources目录,在这个resources目录中存放着所有的application_XX_XX.properties资源属性文件

7. 如何用程序切换网页显示的语言

struts利用在session中存放一个Locale对象来达到设置当前语言的目的

默认的情况下,struts根据网页向后台提交时所包含的语言编码信息来提供缺省的Locale对象,这就是我们为什么可以通过更改网页显示语言设置,就能显示不同的语言文字的原因。

strutssession中存放的这个Locale对象,取名为:Globals.LOCALE_KEY 的值,Globalsstruts框架提供的一个对象

利用这个原理,我们可以用编程的方式来手工切换整个应用系统的语言。

举例说明

ChangeLanguageAction

String lan = request.getParameter("lan");

if(lan != null && lan.equals("zh")){

//把当前系统的语言切换为中文

request.getSession().setAttribute(Globals.LOCALE_KEY,Locale.CHINA);

}else{

request.getSession().setAttribute(Globals.LOCALE_KEY,Locale.ENGLISH);

}

8. Struts消息处理

为什么需要消息处理?

比如登录成功的提示

比如创建失败的提示

等等……总之,程序总是要通过界面来跟用户交互,所以,在交互的过程中,就产生了众多的消息文本

struts提供了专门的处理机制,来将这些消息文本国际化,避免消息文本的硬编码

消息处理,就是在ActionJSP之间传递的消息文本的处理(区别于JSP页面硬编码文本的消息,JSP页面消息可以使用<bean:message/>标签来处理)

Struts交互消息,是通过ActionMessages等对象,以及相应的<html:messages/>标签来处理的

9. 如何创建消息对象?

ActionMessagesActionMessage对象

ActionMessages对象是ActionMessage对象的集合

一个ActionMessage对象,代表一个国际化消息文本(字符串)

如何创建ActionMessages对象?

ActionMessages messages = new ActionMessages();

如何创建ActionMessage对象?

ActionMessage msg = new ActionMessage(key);

其构造方法带的参数,就是一个在资源属性文件中的key,所以,它能表示一个国际化消息文本

如何将ActionMessage对象添加到ActionMessages对象中?

messages.add(message_id,msg);

第一个参数(message_id)表示本ActionMessage对象在ActionMessages对象中区别于其它ActionMessage对象的标识符

10. 如何将消息对象从Action中传递到下一个页面(JSP)

首先我们要决定的是,我们要传递的消息是普通消息还是错误消息?

普通消息:即普通的消息文本

错误消息:即提示错误的消息文本

本质上,这两种消息没有什么区别,都是消息文本,但是如果一个页面同时需要显示普通的消息文本和错误消息文本的时候,就需要进行区分了,比如不同类型的消息文本可能要用不同的样式来显示

通过一句简单的代码,将ActionMessages对象保存到HttpServletRequest对象中

保存普通消息:this.saveMessages(request,messages);

保存错误消息:this.saveErrors(request,messages);

这就是调用父类(Action)所提供的方法saveMessages()/saveErrors()来保存消息对象

实际上,父类的saveMessages()方法,将消息对象保存在了request中,并命名为Globals.MESSAGE_KEY

saveErrors()方法,将消息对象保存在了request中,并命名为Globals.ERROR_KEY

11. 如何在JSP中使用消息对象?

使用<html:messages/>标签来显示消息

<html:messages/>标签既可以显示普通消息,也可以显示错误消息

<html:messages/>标签的重要属性:

name 消息对象的名称,如果我们调用saveMessages/saveErrors方法来传递消息,那么这个名字不需要标识(struts使用缺省的名称,即Globals.MESSAGE_KEY Globals.ERROR_KEY

id (这是必需的属性)因为我们传递的是ActionMessages对象,而不是ActionMessage对象,ActionMessages对象相当于一个集合,我们需要在JSP上依次输出它所包含的消息,因此需要一个id标识一个变量来临时存放其每条消息(与<logic:iterate/>标签的id属性的意义是一样的)

property 我们传递的ActionMessages对象,包含了多条消息文本,如果我们只需要显示其中一条,则可以通过property属性来指定显示哪条消息

message 可以取值为truefalse,如果取值为true,将显示普通消息,如果取值为false,将显示错误消息

12. <html:errors/>标签

<html:errors/>标签只显示错误消息

<html:errors/>标签与<html:messages/>标签类似,但无id属性

<html:errors/>标签通过提供header/footer属性以及prefix/suffix属性来定制每条消息的显示格式

header/footer 定义整个错误消息显示之前(之后)要显示的内容,这些内容也是在资源属性文件中定义的一些key值,默认的情况下,它们的取值分别为:errors.headererrors.footer

prefix/suffix 定义每条错误消息显示之前(之后)要显示的内容,这些内容也是在资源属性文件中定义的一些key值,默认的情况下,它们的取值分别为:errors.prefixerrors.suffix

举例如下:

errors.header=<UL>

errors.prefix=<LI>

errors.suffix=</LI>

errors.footer=</UL>

13. Struts的异常自动处理机制

编程式异常处理

即我们在Action中调用业务逻辑层对象的方法时,用try{ }catch的方式来截获异常之后,手工对异常进行处理

我们以前的开发过程中,都是使用编程式的异常处理

在编程式异常处理的时候,我们可以使用struts的消息处理机制(前面所讲的内容)来对这些异常信息进行处理

自动异常处理机制

即在Action中不捕捉异常,而是将异常抛出给struts框架处理

我们需要在配置文件中指示struts如何处理这些被抛出的异常

使用<exception/>元素来定义自动异常处理

14. <exception/>元素的配置及使用

<exception/>元素的配置,指示了struts如何处理异常的方式

在通常的情况下,我们得到异常以后,需要将页面导航到一个错误提示的页面,提示错误信息

<exception/>元素配置的关键属性是:

key 即这个异常所对应的错误提示消息文本的key,这个key的值,需要在资源属性文件中进行定义

type 即定义需要处理哪种类型的Exception

path 定义一旦出现异常,需要转向哪个页面来进行提示,如果不定义path属性,默认情况下,将使用Action配置中的input属性的值来作为转向的页面

如何显示错误消息?

JSP页面中,使用<html:errors/>标签,即可将其异常对应的错误消息文本进行显示(测试login.jsp页面)

更多相关文章

  1. 关于 jq/js获取几层/多层frame/frameset的对象,怎么获取
  2. 请问json文件在html head中以script的形式导入了,怎样读取这个jso
  3. 传入连接对象或在类中创建它? (OOP)
  4. 尽管“SQL语法错误”消息仍然成功执行
  5. 利用ApnsPHP包向IOS推送消息
  6. PHP结合memcacheq消息队列解决并发问题
  7. CakePHP2 Request请求对象中文教程
  8. 如何使用php和mysql处理加密的私人消息
  9. 电商网站项目总结(面向对象编程篇)

随机推荐

  1. PHP中 __toString()方法详解
  2. 安装docker和docker-compose
  3. PHP 实现守护进程
  4. PHP中 __wakeup()方法详解
  5. PHP中__debugInfo()魔术方法详解
  6. php中如何使用魔术变量__line__
  7. PHP中__sleep()方法详解
  8. laradock环境docker-compose操作
  9. PHP语法:goto 语句
  10. PHP中__unset()方法详解