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 学习指南》
相关推荐
二、SpringMVC国际化实现步骤 1. **创建资源文件** 在SpringMVC项目中,我们需要创建两个或更多的.properties文件,分别代表不同的语言。例如,对于英语和简体中文,我们可以创建`messages_en.properties`和`...
- springMVC-master这个文件名暗示了项目的根目录,里面可能包含了SpringMVC项目的源代码、配置文件、资源文件等。 - 通常,项目的目录结构包括src/main/java(存放Java代码)、src/main/resources(存放资源配置...
6. **国际化**:内置了便捷的国际化支持,可以轻松实现多语言环境下的应用开发。 7. **RESTful支持**:对RESTful风格的HTTP请求提供了良好的支持,包括HTTP方法、路径变量和查询参数的处理。 8. **拦截器**:扩展...
实际上,SpringMVC支持拦截器、上传下载文件、异步处理、AOP(面向切面编程)、国际化等功能,可以满足各种复杂的Web应用需求。深入学习SpringMVC,你将能够更有效地构建健壮的Java Web应用。 在学习过程中,结合...
它简化了开发过程,提供了强大的依赖注入、数据验证、国际化等功能。本教程将通过 "springmvc-helloworld" 这个示例项目,帮助你了解如何搭建 SpringMVC 环境以及其工作原理。 ### 一、SpringMVC 架构 SpringMVC ...
本笔记主要关注SpringMVC中的几个关键特性:数据格式化、数据校验、错误提示、错误信息国际化以及如何返回JSON数据。 1. 数据格式化: 在SpringMVC中,数据格式化是将用户输入的数据转换为业务对象的过程。这通常...
在SpringMVC框架中,语言国际化是一项重要的功能,它使得应用程序能够根据不同用户的语言偏好展示相应的内容。本笔记将深入探讨如何实现SpringMVC中的语言国际化,以及在配置过程中可能遇到的问题。 1. **理解语言...
这个"springmvc国际化demo"就是这样一个实例,它演示了如何在页面和Java代码中获取并使用国际化资源,帮助开发者更好地理解和应用这一特性。在实际项目中,可以扩展这个例子,增加更多的语言支持,以满足不同地区的...
它是一个模型-视图-控制器(MVC)架构,提供了处理HTTP请求、数据绑定、验证、国际化等功能。SpringMVC的优势在于它的松耦合和可测试性,使得开发者能够更高效地构建和维护大型应用。 Bootstrap3则是Twitter开源的...
SpringMVC支持国际化,通过ResourceBundleMessageSource Bean来加载不同语言的资源文件。在视图层,可以使用fmt标签来显示本地化消息。对于视图的处理,可以使用<mvc:view-controller>直接映射URL到视图,或者通过...
总的来说,SpringMVC通过`MessageSource`、资源文件以及`spring:message`标签提供了完善的国际化支持。开发者只需要根据项目需求配置资源文件,设置`MessageSource`,并在Controller和视图中适当地使用,就可以轻松...
3. src/main/resources:资源配置文件,如数据库连接配置、国际化资源等。 4. webapp/WEB-INF:Web应用目录,其中web.xml是Web应用的部署描述符,可能包含DispatcherServlet的配置。 5. webapp/WEB-INF/views:视图...
它是一个模型-视图-控制器(MVC)架构,能够有效地分离业务逻辑与用户界面,提供灵活的数据绑定、声明式验证、国际化等功能。SpringMVC-5.0.4是Spring框架的一个稳定版本,包含了对Java EE 8的支持,改进了WebFlux...
8. **国际化与本地化**:SpringMVC支持多语言环境,通过资源文件配置,可以提供不同语言版本的页面内容。 9. **拦截器**:通过实现`HandlerInterceptor`接口或使用`@Interceptor`注解,可以创建自定义拦截器,执行...
它是一个模型-视图-控制器(MVC)架构的实现,提供了强大的数据绑定、验证、国际化等功能,极大地简化了Java Web开发。在“springMVC学习--基本的几个例子”这个主题中,我们将深入探讨SpringMVC的基础配置以及几个...
国际化(i18n)是任何应用都需要考虑的重要功能,它允许应用程序为不同的地区和语言提供定制的显示内容。在Spring MVC中实现国际化,我们可以利用Spring提供的`MessageSource`接口和资源文件来实现。 首先,我们...
#### 十一、国际化 - **多语言支持**:通过配置不同的消息资源文件(如messages_xx.properties)来支持多语言环境。 - **日期格式化**:可以通过配置日期格式化规则来适应不同地区的日期显示习惯。 #### 十二、...
如果应用需要支持多语言,SpringMVC提供了`MessageSource`接口和`@MessageSource`注解,可以轻松实现国际化。 这个"HelloWeb"实例是学习SpringMVC的一个好起点,通过实践,你可以逐步理解SpringMVC的工作原理,为...
#### 一、SpringMVC国际化(Internationalization, i18n) **1.1 国际化的概念** 国际化的目的是使应用程序能够适应不同的语言和地区设置,以便用户能够在自己的语言环境中使用应用程序。对于Web应用而言,国际化...
本项目“SpringMVC-demo”提供了一个完整的示例,旨在帮助开发者理解并掌握SpringMVC的基本使用和核心概念。 1. **SpringMVC 概述** SpringMVC 作为模型-视图-控制器(Model-View-Controller)架构的实现,它将...