提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力

国际化

简单来说,国际化就是让应用(app、web)适应不同的语言和地区的需要,比如根据地区选择页面展示语言。

i18n=internationalization,首末字符i和n,18为中间的字符数

原理

基于传入语言or地区标识进行判断,输出不同内容。伪代码如下:

提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力_第1张图片

原理简单,但是如何优雅的实现?spring是否已经提供了现成的轮子?答案是肯定的。基于原理可以认为,实现国际化主要分为2部分

  1. 输入语言or地区标识
  2. 输出不同语言or地区的内容文案

输出

通过MessageSource实现不同语言输出。

在spring初始化refresh过程中,会初始化MessageSource。

提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力_第2张图片

而springboot会初始化ResourceBundleMessageSource实例作为MessageSource的默认实现

提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力_第3张图片

MessageSource内部则通过basename以及Locale定位到具体Resource Bundle文件,并基于code(properties key)读取对应的显示文本。

其中涉及到的三个概念

  1. basename标识
  2. Locale
  3. Resource Bundle

basename

用于指定Resource Bundle文件位置,可以通过配置文件配置, 默认为messages

spring.messages.basename=messages


Locale

Locale对象代表具体的地理,政治或文化地区,用来指定语言及地区。构造函数如下

25941543201b15f6915be962c5ce559b.jpeg

variant 变体值,用于指示变化的任意值Locale。 同时, Locale类内置了众多常用国家地区的常量实例,如

提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力_第4张图片

Resource Bundle

ResourceBundle类和Properties类似,都可以读取程序内的文件,不过ResourceBundle更强大,提供了诸如缓存、Locale区分一类的操作。

所以MessageSource其实是对ResourceBundle的一种封装增加,优化了使用,并且托管与spring容器生命周期。这时就有一个很重要的选择:

如果通过静态类封装了restful的接口返回,可以自己扩展ResourceBundle类,而不是将MessageSource的spring实例放置在静态类中。

而idea中提供了Resource Bundle资源束的支持,方便用户添加管理国际化文案。



输入

看完输出的形式,可以知道,我们只需要确认Locale就可以实现国际化。所以我们再找一下Locale的轮子。

accept-language

servlet自带轮子,基于http协议,即通过header中的accept-language报文头,实现Locale的自动识别。

代码见 org.apache.catalina.connector.Request

提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力_第5张图片

spring提供的轮子

  1. LocaleResolver 实现次接口,用于自定义解析规则
  2. RequestContextUtils 基于request获取Locale,优先使用自定义LocaleResolver
  3. LocaleContextHolder通过ThreadLocal持有Locale对象,在FrameworkServlet支持servlet.service时执行初始化。
  4. LocaleChangeInterceptor通过Configuration配置Locale切换规则

综上,只要请求方在header中增加了accept-language报文头,即可在代码中通过LocaleContextHolder获取Locale对象。

提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力_第6张图片

lang

除了accept-language外,常见在url中增加了国家及地区参数,如: https://twitter.com/?lang=zh

通过lang配置国际化,需要通过LocaleChangeInterceptor进行配置,此配置的优先级高于accept-language

提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力_第7张图片

Test Case

提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力_第8张图片

LanguageTagCompliant

Locale的命名规则为 lang-country, 如: zh-CN,有时会看到zh_CH这种写法,这是另一种规范,可以在CookieLocaleResolver了解规范定义

提升用户体验的利器:揭秘Spring框架中国际化的奇妙魔力_第9张图片

需要在中LocaleChangeInterceptor开启兼容模式

92398c59c9b78bce402af8a103dcc1fb.jpeg

但是为了符合规范,不推荐zh_CH这种写法。

倾向

按照《Http参数格式约定》文中所述,通用&非业务参数,一般会选择放到header中,所以比较倾向于accept-language这种定义方法。

你可能感兴趣的:(spring,spring,boot,java,后端)