1、国际化语言代码
ISO-639 标准使用编码定义了国际上常见的语言,每一种语言由两个小写字母表示。
ISO-3166 标准使用编码定义了国家/地区,每个国家/地区由两个大写字母表示。
国家/地区 | 语言代码 |
简体中文(中国) | zh-CN |
繁体中文(台湾地区) | zh-TW |
繁体中文(香港) | zh-HK |
英语(英国) | en-GB |
英语(美国) | en-US |
英语(香港) | en-HK |
英语(全球) | en-WW |
2、HTTP中的常见首部
1)请求首部
请求首部中的Accept首部为客户端提供了一种将其喜好和能力告知服务器的方式,包括他们想要什么,可以使用什么,以及最重要的他们不想要什么。这样服务器就能根据这些额外信息,对要发送的内容做出更明智的决定。
请求首部 | 描述 |
Accept | 告知服务器发送何种媒体类型,例如:*/* |
Accept-Language | 表示浏览器所支持的语言,告知服务器发送何种语言 |
Accept-Charset | 告知服务器发送何种字符集 |
Accept-Encoding | 告知服务器采用何种编码 |
2)响应首部
响应首部 | 描述 |
Accept-Range | 对此资源来说,服务器可接受的范围类型 |
Set-Cookie | 在客户端写入cookie数据 |
3)实体首部
实体首部可以告知报文的接收者它在对什么进行处理
实体首部 | 描述 |
Content-Type | 主体的对象类型 |
Content-Language | 理解主体时最适宜使用的自然语言 |
Content-Encoding | 主体的编码方式 |
Content-Length | 主体的长度或尺寸 |
Content-MD5 | 主体的MD5校验和 |
Content-Range | 在整个资源中此实体标识的字节范围 |
3、Java中的Locale
在 Java 中,一个 java.util.Locale
对象表示了特定的地理、政治和文化地区。需要 Locale 来执行其任务的操作称为语言环境敏感的操作,它使用 Locale 为用户量身定制本地信息。
它有三个构造方法
Locale(String language)
:根据语言编码初始化Locale(String language, String country)
:根据语言编码、国家编码初始化Locale(String language, String country, String variant)
:根据语言编码、国家编码、变体初始化
此外,Locale 定义了一些常用的 Locale 常量:Locale.ENGLISH
、Locale.CHINESE
等。
4、Java中的国际化
1)国际化文件格式:<资源名>_<语言代码>_<国家/地区编码>.properties
2)国际化文件处理:native2ascii [-reverse] [-encoding 编码] [输入文件 [输出文件]]
注:<资源名>.properties
命名的国际化资源文件是默认的资源文件,即某个国际化类型在系统中找不到对应的资源文件,就采用这个默认的资源文件
3)国际化文件加载:Java提供了用于加载资源文件的工具java.util.ResourceBoundle
ResourceBoundle
提供了多个名为 getBundle
的静态重载方法,这些方法的作用是用来根据资源名、Locale 选择指定语种的资源文件。
需要说明的是: getBundle
方法的第一个参数一般都是baseName
,这个参数表示资源文件名。
Java 中也提供了几个支持国际化的格式化工具类。例如:NumberFormat
、DateFormat
、MessageFormat
5、SpringMVC读取客户端语言列表
- jakarta.servlet.ServletRequest的getLocales方法从请求头中读取Accept-Language构建出Locale集合
- org.springframework.web.servlet.FrameworkServlet调用ServletRequest的getLocale方法获取第一个Locale
- 将Locale对象封装成LocaleContext,并设置到LocaleContextHolder中,其它地方便可直接从LocaleContextHolder中获取Locale信息
6、LocaleResolver
基于web的Locale设置解析策略的接口,既允许通过请求进行Locale设置解析,也允许通过请求和响应进行Locale设置修改。
此接口允许基于request, session, cookie等的实现。默认实现为org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver,只需使用相应HTTP标头提供的请求的区域设置。
使用org.springframework.web.servlet.support.RequestContext.getLocale()来检索控制器或视图中的当前区域设置,与实际的解析策略无关。
调用HttpServletRequest的getLocale方法便能获取到Locale信息,通过AcceptHeaderLocaleResolver可以设置所有支持的Locale,也可以设置默认的Locale。
当DispatcherServlet执行render方法时,会执行以下逻辑
1)如果localeResolver不为null,则通过localeResolver来解析Locale,否则调用Request的getLocale()方法获得Locale
2)将上一步得到的Locale设置到HttpServletResponse上
3)将上面的Locale作为参数执行ViewResolver的resolveViewName方法
请注意,AcceptHeaderLocaleResolver解析器无法改变用户的区域,因为它无法修改用户操作系统的区域设置。
7、LocaleChangeInterceptor
除了显式调用LocaleResolver.setLocale()来修改用户的区域之外,还可以将LocaleChangeInterceptor拦截器应用到处理程序映射中,它会发现当前HTTP请求中出现的特殊参数。其中的参数名称可以通过拦截器的paramName属性进行自定义。如果这种参数出现在当前请求中,拦截器就会根据参数值来改变用户的区域。
执行逻辑:
1)从请求的查询参数说获取Locale信息(参数名可自行设置),如果不为空则继续处理
2)获取使用的LocaleResolver
3)解析从参数获取到的区域信息,构建Locale实例对象
4)调用localeResolver的setLocale方法设置Locale
需要注意的是,如果使用的是AcceptHeaderLocaleResolver则会报错UnsupportedOperationException,所有在使用LocaleChangeInterceptor是记得配置LocaleResolver,例如使用CookieLocaleResolver
使用后的效果:
假设有以下请求
http://localhost:8080/court/welcome.htm?language=en_US
LocaleChangeInterceptor会读取参数language(先配置了该参数),然后将转换成的Locale设置到LocaleResolver(假设此时用的是CookieLocaleResolver),CookieLocaleResolver后续会将区域信息写入客户的cookie中。
在后续的请求中会从cookie中读取区域信息。这样,随时可以通过url地址来改变用户的区域信息。
8、读取国际化数据
SpringMVC提供了org.springframework.context.MessageSource类型来获取国际化配置数据,自然也可以通过ApplicationContext的getMessage方法来获取。