简介
通俗的讲,将一个页面里面的内容抽取出来,分类的创建一个个资源包, 这些资源包分别对应着不同国家的语言,在需要的时候,会根据条件来切换目标的资源包。
在 SpringBoot 中,搭配 Thymeleaf 模板引擎,可以识别浏览器语言,自动切换资源包。
使用
单纯的 SpringMVC 需要完成以下几步:
- 编写国际化配置文件
- 使用 ResourceBundleMessageSource 管理国际化资源文件
- 在页面使用 fmt:message 取出国际化内容
SpringBoot 国际化
现在在 SpringBoot 中,不需要另外的手动配置,内置了自动配置。
在 SpringBoot 中,简化了步骤:
- 编写国际化资源包
- 使用国际化内容
国际化资源包
国际化资源包文件必须是:.properties
后缀,同时在 IDEA 中,也有相应的可视化支持。
- 在项目的 resources 目录创建一个:i18n 目录,存放资源包
- 创建
Resource Bundle
文件- 这种文件,IDEA 支持可视化编辑
- 这种文件,IDEA 支持可视化编辑
使用国际化内容
搭配 Thymeleaf 模板引擎,可以使用特定的语法从资源包中获取对应内容。
<form class="form-signin" action="dashboard.html">
<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}"></h1>
<label class="sr-only" th:text="#{login.user}"></label>
<input type="text" class="form-control" th:placeholder="#{login.user}" required="" autofocus="">
<label class="sr-only" th:text="#{login.password}"></label>
<input type="password" class="form-control" th:placeholder="#{login.password}" required="">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> [[#{login.remember}]]
</label>
</div>
<button class="btn btn-lg btn-primary btn-block" type="submit" th:text="#{login.sign}"></button>
</form>
#{...}:Thymeleaf 模板引擎国际化语法,花括号里面是资源包里面的键。
就这样简单的使用,根据浏览器的语言,来自动切换,当然若是没有匹配的资源包,则使用默认的,也就是不在任何后缀的资源包。
自动配置类
SpringBoot 自动配置文件类:org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration
@Bean
public MessageSource messageSource(MessageSourceProperties properties) {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
if (StringUtils.hasText(properties.getBasename())) {
messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
StringUtils.trimAllWhitespace(properties.getBasename()))
);
}
if (properties.getEncoding() != null) {
messageSource.setDefaultEncoding(properties.getEncoding().name());
}
messageSource.setFallbackToSystemLocale(properties.isFallbackToSystemLocale());
Duration cacheDuration = properties.getCacheDuration();
if (cacheDuration != null) {
messageSource.setCacheMillis(cacheDuration.toMillis());
}
messageSource.setAlwaysUseMessageFormat(properties.isAlwaysUseMessageFormat());
messageSource.setUseCodeAsDefaultMessage(properties.isUseCodeAsDefaultMessage());
return messageSource;
}
其中,特别需要注意的一点是:
messageSource.setBasenames(StringUtils.commaDelimitedListToStringArray(
StringUtils.trimAllWhitespace(properties.getBasename()))
);
这行代码表示,设置一个基础名,也就是资源包去除其他后缀名,剩下的相同的部分,如:
前面的 messages 就是基础名,可以通过在配置文件中设置,例如资源包在:resoureces/i18n
spring.messages.basename=i18n/basename
必须要带上目录名称,否则找不到对应的资源包。
自定义国际化
下面我们自定义区域解析器,这里是根据你的定制规则实现的,我的定制规则是将国际化信息放在了请求中。
切换国际化的两个按钮
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
自定义解析器:
package com.huasio.learning.demo.component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
/**
* @author yu
*/
public class UserLocaleResolver implements LocaleResolver {
@Override
public Locale resolveLocale(HttpServletRequest request) {
System.out.println(123);
// 1. 获取到区域信息
String l = request.getParameter("l");
// 2. 获取系统默认的区域信息或者请求头区域信息
Locale locale = Locale.getDefault();
// 3. 创建一个自定义区域对象
if (!StringUtils.isEmpty(l)) {
String[] split = l.split("_");
locale = new Locale(split[0], split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
throw new UnsupportedOperationException(
"Cannot change HTTP accept header - use a different locale resolution strategy");
}
}
注册组件:
@Bean(name = "localeResolver")
public LocaleResolver localeResolver() {
return new UserLocaleResolver();
}
可以使用 @Bean 其中 name 的属性,来设置 bean id。
注意:方法名一定是 localeResolver,否则是无法匹配到的。
配置
配置项 | 描述 |
---|---|
spring.messages.basename | 设置资源包的基础文件名称,该名称是资源包前缀。 以逗号分隔的 basenames 列表(本质上是一个完全限定的类路径位置)。 每个都遵循ResourceBundle 约定,并且放宽了对基于斜杠的位置的支持。 如果它不包含包限定符(例如“org.mypackage”),它将从类路径根解析。 |
spring.messages.encoding | 资源包编码。 |
spring.messages.always-use-message-format | 是否始终应用MessageFormat规则,甚至在不带参数的情况下解析消息。 |
spring.messages.cache-duration | 加载的资源包文件缓存持续时间。当未设置时,包将被永久缓存。如果没有指定持续时间后缀,将使用秒。 |
spring.messages.fallback-to-system-locale | 如果没有找到特定语言环境的文件,是否退回到系统语言环境。如果这是关闭的,唯一的备份将是默认文件。”messages.properties“ 用于 basename “messages”)。 |
spring.messages.use-code-as-default-message | 是否使用消息代码作为默认消息,而不是抛出“NoSuchMessageException”。只建议在开发期间使用。 |
Q.E.D.
Comments | 0 条评论