持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情
Spring配置
配置拦截器及语言环境解析
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
//设置cookie模式处理国际化
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setDefaultLocale(Locale.CHINESE);
return cookieLocaleResolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//指定国际化标识
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
registry.addInterceptor(localeChangeInterceptor);
}
}
- LocaleResolver:指定存储本地化标识的处理类,这里使用的是cookie,还可以使用SessionLocaleResolver,AcceptHeaderLocaleResolver这个是依据请求头中language指定即浏览器语言,不支持修改。
- LocaleChangeInterceptor:指定语言设置参数名称默认为locale
配置国际化数据源
@Component("messageSource")
public class DBMessageSource extends AbstractMessageSource {
// 自定义service
@Autowired
private LanguageRepository languageRepository;
// 2.国际化处理方法依据key在数据库中查找对应国际化内容
@Override
protected MessageFormat resolveCode(String key, Locale locale) {
LanguageEntity message = languageRepository.findByKeyAndLocale(key,locale.getLanguage());
if (message == null) {
message = languageRepository.findByKeyAndLocale(key,Locale.getDefault().getLanguage());
}
return new MessageFormat(message.getContent(), locale);
}
//3.新增方法,用于后端传参国际化
public final String getMessage(String code, @Nullable Object[] args) throws NoSuchMessageException {
Locale locale = LocaleContextHolder.getLocale();
String msg = getMessageInternal(code, args, locale);
if (msg != null) {
return msg;
}
String fallback = getDefaultMessage(code);
if (fallback != null) {
return fallback;
}
throw new NoSuchMessageException(code, locale);
}
}
- messageSource为spring上下文中,国际化资源处理bean固定名称,需覆盖默认配置。
- AbstractMessageSource:抽象资国际化资源处理类,下面子类中就有我们常用的配置文件支持ResourceBundleMessageSource,ReloadableResourceBundleMessageSource
- LocaleContextHolder:使用ThreadLocal存储上下文中国际化标识,还存储了时区信息
- args:这里的参数也是支持国际化的,最终会使用MessageFormat.format来格式化
thymeleaf 页面使用
<h2 th:text="#{home.welcome('xxx')}"></h2>
<p th:text="#{home.info}"></p>
<p th:text="#{home.changelanguage}"></p>
<ul>
<li><a href="?lang=en" th:text="#{home.lang.en}"></a></li>
<li><a href="?lang=de" th:text="#{home.lang.de}"></a></li>
<li><a href="?lang=zh" th:text="#{home.lang.zh}"></a></li>
</ul>
参数传递为#{key(参数……)}
遗留问题:
- Thymeleaf中[[]]为转义符导致在js代码中使用国际化并不方便,需将国际化内容定义与js业务代码分开。
- 如何整合现在流行的前端国际化库使用动态国际化资源,如i18next。