Java 国际化与格式化
国际化是指应用程序运行时,可根据客户端请求来自的国家语言的不同而现实不同的界面。
国际化的英文单词是:internationalization,所以简称 I18N,18表示中间省略了18个字母。
-
国际化(internationalization) 简称i18n,是一种让软件在开发阶段就支持多种语言的技术
-
java.util.Locale 语言代码_国家代码 注:国家代码可省略 zh_CN en_US
//zh_CN 语言代码_国家代码 Locale locale = Locale.getDefault(); System.out.println(locale); Locale l2 = Locale.US; System.out.println(l2); String[] countries = Locale.getISOCountries(); System.out.println(countries.length); String[] langs = Locale.getISOLanguages(); System.out.println(langs.length);
-
创建资源文件
资源文件就是 key-value 对,每个资源文件中的 key 是不变的,但是value 随着不同的国家语言而改变;
user.username=jack hello=hello:{0}
-
java.util.ResourceBundle用于加载国家、语言资源包
public static void main(String[] args) { // Locale locale = Locale.getDefault(); Locale locale = Locale.US; ResourceBundle message = ResourceBundle.getBundle("i18n",locale); System.out.println(message.getString("user.username")); }
-
java.text.MessageFormat处理资源文件中的占位符
public static void main(String[] args) { //1.Locale用于封装特定的国家/区域、语言环境 Locale locale = Locale.getDefault(); // Locale locale = Locale.US; //2.ResourceBundle用于加载国家、语言资源包 ResourceBundle message = ResourceBundle.getBundle("i18n",locale); System.out.println(message.getString("user.username")); String userName = message.getString("user.username"); String hello = message.getString("hello"); //3.MessageFormat处理资源文件中的占位符 String helloStr = MessageFormat.format(hello,userName); System.out.println(helloStr); }
springMVC国际化与格式化
基于浏览器语言顺序
-
添加资源文件
i18n_zh_CN.properties i18n_en_US.properties
-
修改springMVC.xml,加载资源文件
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <!-- 国际化信息所在的文件名 --> <property name="basename" value="i18n" /> </bean>
-
jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <!--导入标签库--> <%@taglib prefix="s" uri="http://www.springframework.org/tags" %> <html> <head> <title>Title</title> </head> <body> <!--国际化输出--> hello:<s:message code="author"/> </body> </html>
-
在controller中添加跳转到jsp页面的方法
@RequestMapping("/i18n") public String i18n(){ return "i18n"; }
-
测试
基于session实现
-
在原有配置基础上,在springMVC.xml中添加以下配置
<mvc:interceptors> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" /> </mvc:interceptors> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
-
在controller中添加改变当前语言的方法
public String change(String lang, HttpSession session){ if(lang.equals("zh")){ Locale locale = new Locale("zh","CN"); session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,locale); }else if(lang.equals("en")){ Locale locale = new Locale("en","US"); session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,locale); }else{ session.setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME,Locale.getDefault()); } return "i18n"; }
-
修改jsp页面,添加链接
<a href="change?langType=zh">中文</a> | <a href="change?langType=en">english</a><br/>
LocaleResolver
-
按HTTP请求头部解析区域
Spring采用的默认区域解析器是AcceptHeaderLocaleResolver。它通过检验HTTP请求的accept-language头部来解析区域。这个头部是由用户的web浏览器根据底层操作系统的区域设置进行设定。请注意,这个区域解析器无法改变用户的区域,因为它无法修改用户操作系统的区域设置。
-
按会话属性解析区域
解析区域的另一种方法是通过SessionLocaleResolver。它通过检验用户会话中预置的属性来解析区域。如果该会话属性不存在,它会根据accept-language HTTP头部确定默认区域。
-
按Cookie解析区域
可以检验用户浏览器中的Cookie,用CookieLocaleResolver来解析区域。如果Cookie不存在,它会根据accept-language HTTP头部确定默认区域。
-
FixedLocaleResolver
一直使用固定的Local, 改变Local 是不支持的 。
数据验证框架-JSR 303
B/S系统中对http请求数据的校验多数在客户端进行,这也是出于简单及用户体验性上考虑,但是在一些安全性要求高的系统中服务端校验是不可缺少的,本节主要学习springmvc实现控制层添加校验。
Spring支持JSR-303验证框架,JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,官方参考实现是Hibernate Validator(与Hibernate ORM 没有关系),JSR 303 用于对Java Bean 中的字段的值进行验证。
POM.XML
<!--hibernate validator--> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.1.6.Final</version> </dependency>
添加验证规则
public class DemoPojo { @NotNull(message = "不能为空") private Integer id; @Length(min = 6,message="最小长度为6") private String name; //..省略get/set方法.. }
捕获错误
@RequestMapping("/demo/toedit") public String toedit(@Validated DemoPojo item, BindingResult result){ return "demo_edit"; } @RequestMapping("/demo/edit") public String edit(@Validated @ModelAttribute("item") DemoPojo item, BindingResult result, Model model){ if(result.hasErrors()){ List<FieldError> list = result.getFieldErrors(); Map<String,String> map = new HashMap<>(); for (FieldError error : list){ map.put(error.getField(),error.getDefaultMessage()); } model.addAttribute("errors",map); return "demo_edit"; } return "redirect:hello"; }
显示错误消息
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@taglib prefix="sf" uri="http://www.springframework.org/tags/form" %> <html> <body> <form action="edit"> <p>编号<sf:input name="id"/>${errors.id}</p> <p>名称<input type="text" name="name" value="${item.name}"/>${errors.name}</p> <p><input type="submit" value="保存"/></p> </form> </body> </html>