ResourceBundle类
上一章《java国际化之(一)---jdk相关api》,主要对jdk中对国际化支持的API进行了讲解。在jdk国际化api中还有一个重要的类上一章没讲---ResourceBundle类,该类会在spring MVC国际化读取配置的时候用到,所以放到这次讲解。
现在来看下ResourceBundle类,它能轻松的选择和读取特定用户语言区域配置文件,并根据指定key查询对应的属性值。ResourceBundle是个抽象类,要想创建它的实例对象,只能通过调用其静态工厂方法getBundle方法实现。通过阅读该方法的源码可以发现,其最终会创建一个PropertyResourceBundle类的实例(PropertyResourceBundle是ResourceBundle的子类类),配置文件是.properties类型,并读取配置文件中的值放到HashMap中,关键源码如下:
// stream为从.properties配置文件读入的输入流 bundle = new PropertyResourceBundle(stream); // PropertyResourceBundle的构造方法 public PropertyResourceBundle (InputStream stream) throws IOException { Properties properties = new Properties(); properties.load(stream); lookup = new HashMap(properties); }
我们再来看getBundle方法的定义:
public static final ResourceBundle getBundle(String baseName, Locale locale) public static final ResourceBundle getBundle(String baseName)//自动获取默认的locale
baseName为配置文件的 “基准名”,用户可以任意定义,假设这里定义为” message”; locale为区域语言,比如汉语_中国,通过zh_CN表示。最终确定的配置文件即为:messages_zh_CN.properties,如果没有找到该文件,会自动寻找默认文件messages.properties,如果也没找到,抛出MissingResourceException异常。
看个例子,首先准备三个.properties配置文件,放到程序执行的classpath下。比如 我是在diea中执行的,可以放到编译完成的classes目录下:
messages_en.properties配置文件中的内容为:
productname.required.product.name=Please enter a name price.negative=Invalid price
messages_zh_CN.properties和messages.properties配置文件中的内容相同,内容为:
productname.required.product.name=请输入商品名称 price.negative=价格不合法
再看下main方法:
public static void main(String[] args) { //Locale lc = Locale.CHINA; //汉语中国地区 Locale lc = new Locale("en");//英语地区 ResourceBundle rb = ResourceBundle.getBundle("messages",lc); System.out.println(rb.getString("productname.required.product.name")); }
执行mian方法,打印信息为:
Please enter a name
将lc改为Locale.CHINA,再执行main方法,打印信息为乱码。这是由于java原生支持的是Unicode编码,这里需要把对应的中文转陈Unicode编码。转Unicode可以使用java自带的native2ascii工具,也可以写段程序来实现类似的转换,同时也可以实现反转。这里不对native2ascii工具进行讲解,感兴趣的可以百度下,我们来看下通过程序把汉字转换为Unicode编号的实现:
public static String encodeUnicode(String inStr) { char[] myBuffer = inStr.toCharArray(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < inStr.length(); i++) { char ch = myBuffer[i]; if (ch < 10) { sb.append("\\u000" + (int) ch); continue; } UnicodeBlock ub = UnicodeBlock.of(ch); if (ub == UnicodeBlock.BASIC_LATIN) { // 英文及数字等 sb.append(myBuffer[i]); } else if (ub == UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { // 全角半角字符 int j = myBuffer[i] - 65248; sb.append((char) j); } else { // 汉字 int s = myBuffer[i]; String hexS = Integer.toHexString(Math.abs(s)); String unicode = "\\u" + hexS; sb.append(unicode.toLowerCase()); } } return sb.toString(); } public static void main(String[] args) { System.out.println(encodeUnicode("请输入商品名称")); System.out.println(encodeUnicode("价格不合法")); }
执行mian方法,打印信息为:
\u8bf7\u8f93\u5165\u5546\u54c1\u540d\u79f0 \u4ef7\u683c\u4e0d\u5408\u6cd5
将这些字符用户来替换messages_zh_CN.properties和messages.properties配置文件中的汉字,再次执行上一个mian方法:
public static void main(String[] args) { Locale lc = Locale.CHINA; //汉语中国地区 //Locale lc = new Locale("en");//英语地区 ResourceBundle rb = ResourceBundle.getBundle("messages",lc); System.out.println(rb.getString("productname.required.product.name")); }
打印信息为:
请输入商品名称
关于ResourceBundle类的用法讲解,到处结束。至此我们已经讲解jdk中对国际化支持的相关api,通过这些api我们已经可以实现国际化程序的开发。但我们不用这么麻烦的自己去编码实现国际化,现在主流的mvc框架都提供国际化支持,底层其实就是基于上述讲解的jdk国际化api实现的。了解了java国际化实现原理后,我们接下来看看Spring MVC对国际化的支持。
Spring MVC 国际化配置
Spring MVC的国际化配置主要包含两部分:选择和读取正确的属性配置文件;告诉Spring MVC使用哪种语言区域。
1、选择和读取正确的属性配置文件,是通过ReloadableResourceBundleMessageSource配置,其底层实际上是调用ResourceBundle实现的。配置方式如下:
<!-- 资源文件 --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames" > <list> <value>classpath:/resource/messages</value> <value>classpath:/resource/labels</value> </list> </property> <property name="defaultEncoding" value="UTF-8"/> </bean>
其中messages和labels为国际化配置文件的“基准名”,根据业务的需要可以配置多个。对应的配置文件列表为:
注意:所有配置文件在程序启动时,读入到内存。如果配置文件修改后,需要重新启动程序。
多版本的配置文件准备好后,就要告诉Spring MVC使用哪个国家的配置。
2、告诉Spring MVC使用哪种语言区域:Spring MVC支持4种方式的配置,告诉Spring MVC使用哪种语言区域,根据具体业务场景使用,4种方式分别讲解如下。
A、CookieLocaleResolver:通过cookie方法,该方式会在用户的浏览器cookie中记住用户的区域语言,并在程序运行过程中,获取指定区域语言的属性配置文件里的消息。配置方式如下:
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"> <property name="cookieName" value="clientlanguage"/> <property name="cookieMaxAge" value="94608000"/> <property name="defaultLocale" value="en" /> </bean>
cookieName cookie名称;cookieMaxAge,cookie的过期时间;defaultLocale,默认的区域语言,该方式可以通过构造请求改变cookie中的值,以实现改变区域语言。
B、AcceptHeaderLocaleResolver:通过读取请求头中的accept-language中的区域语言,并在程序运行过程中,获取指定区域语言的属性配置文件里的消息。配置方式如下:
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"> </bean>
该方式,可以在浏览器中修改语言选项完成区域语言的修改。修改方式,以chrome为例:设置—>高级设置à语言和输入设置à添加
然后把需要指定的语言拖动到顶部 保存即可完成修改。
C、SessionLocaleResolver,顾名思义,通过session会话指定语言区域,配置方式如下:
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"> <property name="defaultLocale" value="zh_CN"></property> </bean>
D、FixedLocaleResolver,固定不变的指定语言区域,不能改变。
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.FixedLocaleResolver"> <property name="defaultLocale" value="en" /> </bean>
Spring MVC国际化Formatter支持
上一章讲过jdk中有三大三大格式化类:NumberFormat(数字)、MessageFormat(消息)、DateFormat(日期时间)。在String MVC国际化中,提供了对数字、日期时间处理的默认封装,也可以根据具体的业务实现自己的Formatter。
String MVC国际化对数字支持的默认formatter如下:
NumberFormatter(已不推荐使用)、NumberStyleFormatter(数字);
CurrencyFormatter(已不推荐使用)、CurrencyStyleFormatter(货币);
PercentFormatter(已不推荐使用)、PercentStyleFormatter(百分数)。
String MVC国际化对日期支持的默认formatter如下:
DateFormatter
直接在配置文件中配置即可使用,配置方式为:
<bean id="formatService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <set> <bean class="org.springframework.format.number.CurrencyStyleFormatter"> </bean> <bean class="org.springframework.format.number.NumberStyleFormatter"> </bean> <bean class="org.springframework.format.number.PercentStyleFormatter"> </bean> <bean class="org.springframework.format.datetime.DateFormatter"> </bean> <!--其他自定义formatters--> </set> </property> </bean> <mvc:annotation-driven conversion-service="formatService" />
指定mvc:annotation-driven配置,可以对MVC中的module对象进行自动转换。这里还可以配置自定义的formatters。
自定义的formatter实现方式
Spring MVC自定义的formatter可以实现把String转换为指定的对象,也可以把对象转换为指定locale的字符串格式。定义自定义子类实现org.springframework.format.Formatter接口,接口申明为:
public interface Formatter<T> extends Printer<T>, Parser<T>
其中T为目标对象。子类必须实现其两个方法:
String print(T var1, Locale var2); T parse(String var1, Locale var2) throws ParseException;
看一个例子:
public class LocalDateFormatter implements Formatter<LocalDate> { private DateTimeFormatter formatter; private String datePattern; public LocalDateFormatter(String datePattern) { this.datePattern = datePattern; formatter = DateTimeFormatter.ofPattern(datePattern); } @Override public String print(LocalDate date, Locale locale) { System.out.println(date.format(formatter)); return date.format(formatter); } @Override public LocalDate parse(String s, Locale locale) throws ParseException { System.out.println("formatter.parse. s:" + s + ", pattern:" + datePattern); try { return LocalDate.parse(s, DateTimeFormatter.ofPattern(datePattern)); } catch (DateTimeParseException e) { // the error message will be displayed in <form:errors> throw new IllegalArgumentException( "invalid date format. Please use this pattern\"" + datePattern + "\""); } } }
这里例子实现的是字符串与LocalDate的互转,在sprinp MVC的配置文件中添加即可:
<mvc:annotation-driven conversion-service="formatService" /> <bean id="formatService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="formatters"> <set> <bean class="com.sky.locale.web.controller.formatter.MyDateFormatter"> <constructor-arg type="java.lang.String" value="MM-dd-yyyy" /> </bean> </set> </property> </bean>
Spring MVC国际化的注解支持
如果觉得上述配置方式使用不方便,Spring MVC还支持注解的方式对Number和DateTime提供国际化的Format支持。
NumberFormatAnnotationFormatterFactory:
@NumberFormat注解,实现Number与String之间的解析与格式化,可以通过指定style来指示要转换的格式(Style.Number/Style.Currency/Style.Percent),当然也可以指定pattern(如pattern=“#.##”(保留2位小数) ),这样pattern指定的格式会覆盖掉Style指定的格式。
JodaDateTimeFormatAnnotationFormatterFactory:
@DateTimeFormat注解,实现日期类型与String之间的解析与格式化这里的日期类型包括Date、Calendar、Long以及Joda的日期类型。必须在项目中添加Joda-Time包。
使用方法举例:
public class User { private String name;//姓名 @DateTimeFormat(pattern="yyyy-MM-dd") private Date birthday;//生日 @NumberFormat(style= NumberFormat.Style.CURRENCY) private double money;//资产 public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } }
到这里关于Spring MVC对国际化支持的配置和注解方式总结完毕,下一章将根据这些配置搭建一个国际化demo,整合freemaker作为展示层,并附上示例代码。
参考资料:《Spring 学习指南》
相关推荐
SSM笔记-SpringMVC的数据格式化 、数据校验、错误提示、错误信息国际化、返回json
用springmvc做的一个国际化小例子,包含如何在页面和java代码中获取国际化资源
springmvc 实现i18n国际化+freemarker小实例demo 亲测有用
springmvc+maven+jasperreport解决了中文显示和国际化
SpringMVC入门很简单之国际化,具体参考博文:http://www.cnblogs.com/liukemng/tag/SpringMVC/
极客学院java中级课程,SpringMVC系列教材——SpringMVC 实现文件上传下载、国际化等
本篇文章主要介绍了Java SpringMVC实现国际化整合案例分析(i18n),具有一定的参考价值,感兴趣的小伙伴们可以参考一下
基于Maven管理Spring+SpringMVC+MyBatis(SSM)的国际物流商贸平台 -------- 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源...
全书共计12章,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、传唤器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件多个角度介绍了Spring MVC。除此之外,...
为了实现语言种类切换在网上找了好久的资料,此实例是整合网上的资料通过自己精简生成的实例,调整积分方便下载
《基于SSM框架开发的健身国际俱乐部系统》是一项精心打造的Java毕业设计项目,旨在为健身行业提供一个功能齐全、操作便捷的信息化管理系统。本系统采用流行的SSM(Spring+SpringMVC+MyBatis)框架进行开发,确保了...
本项目为springMVC表单验证简单实例,支持国际化,发布就可以试验效果, 访问路如:http://localhost:8080/springMVC_Validator/register.mvc
SpringMVC demo 完整源码实例,比较完整的SpringMVC的demo,里面包含了对数据增删改查,上传下载文件的实现,异常处理,拦截器,国际化等等功能的实现
样本SpringMVC Spring MVC表单-验证,数据绑定,验证Spring注释-@ RequestParam,@ PathVariable,@ ModelAttribute,@ SessionAttributes Spring安全Spring国际化Spring异常处理Spring基本REST服务用户-hsetpaing...
Struts2 Struts2核心控制流程、Ognl、Action、Interceptor、Result、FreeMarker、Struts2标记库、Struts2扩展、Struts2应用技巧(输入验证、消息国际化、文件上传和下载、防止重复提交等)。 熟练掌握Struts2核心...
国际化 文件上传下载 阶段三:JavaEE主流框架 春天 行动计划 国际奥委会 事物 SpringMVC 运行原理 数据绑定 MyBatis 缓存机制 运行原理 JPA 注解 映射 SpringData 玛文 本地仓库&中央仓库 继承与聚合 吉特 常用...
全书共计12章,分别从Spring框架、模型2和MVC模式、Spring MVC介绍、控制器、数据绑定和表单标签库、传唤器和格式化、验证器、表达式语言、JSTL、国际化、上传文件、下载文件多个角度介绍了Spring MVC。除此之外,...
国际化支持 让我们看看它是如何做到的。 == 1. 独具特色的 RESTful 路由 == 讨厌 _Struts_ 的 Action 配置? 讨厌 _SpringMVC_ 的 @RequestMapping 注解? 讨厌 _JAX-RS_ 的 @Path @GET @POST @DELETE 注解? 如果你...