1. 默认国际化实现
1.1 添加多语言文件
spring boot 默认实现了国际化多语言配置,打开文件 org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration 可以看到,默认的多语言文件放到目录 messages 中,可以通过配置 spring.messages.basename 修改多语言文件存放目录,修改默认配置:
spring: messages: basename: i18n.messages
新建多语言配置文件放到目录 resources/i18n 中:
messages.properties(默认的多语言文件) messages_zh_CN.properties(中文语言文件) messages_en_US.properties(英文语言文件)
messages.properties、messages_zh_CN.properties 中添加如下内容:
login.name=登录
messages_en_US.properties 中添加如下内容:
login.name=Login
1.2 添加控制器
package com.sviping.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Autowired
MessageSource messageSource;
@RequestMapping("/test")
public String test(){
String message = null;
try {
message = messageSource.getMessage("login.name", null, LocaleContextHolder.getLocale());
} catch (NoSuchMessageException e) {
message = "";
System.out.println(e.getMessage());
}
return message;
}
}1.3 测试
浏览器中访问地址 localhost:8080/test 可以看到会返回 登录,修改浏览器的默认语言为英文后,刷新浏览器,会返回 Login,此时配置的默认国际会多语言完成。
2. 自定义国际化实现
上面 spring boot 默认的多语言不够灵活,不能方便的切换语言。通过查看类 org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver 可以发现,spring boot 是根据 header 中 Accept-Language 来切换不同的语言,并且该类型实现了接口 org.springframework.web.servlet.LocaleResolver,所以我们要自己实现多语言切换,也需要实现该接口。这里通过采用类似 AcceptHeaderLocaleResolver 要用不同 Accept-Language 来切换不同语言。
2.1 自定义拦截器
通过添加 url 参数来灵活的修改 Accept-Language ,spring boot 中类 org.springframework.web.servlet.i18n.LocaleChangeInterceptor 已经实现了此功能。该类会将接收到的参数放到 cookie 中, cookie 默认名字为 locale ,同时会添加名为 CookieLocaleResolver.class.getName() + ".LOCALE" 的 request 属性,值为 url 参数生成的 Locale 对象,所以我们只需求添加一个拦截器调用即可。
2.2 修改多语言默认实现
文件 org.springframework.boot.autoconfigure.web.servle.WebMvcAutoConfiguration 中方法 localeResolver 为默认多语言的默认实现方式
@Override
@Bean
@ConditionalOnMissingBean(name = DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME)
public LocaleResolver localeResolver() {
if (this.webProperties.getLocaleResolver() == WebProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.webProperties.getLocale());
}
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.webProperties.getLocale());
return localeResolver;
}通过注解 ConditionalOnMissingBean 可以发现,当 DispatcherServlet.LOCALE_RESOLVER_BEAN_NAME bean 不存在,即 localeResolver bean 不存在,该方法才生效,所以只需要添加 localeResolver bean 就可以自己实现多语言。为了能够实现不用每次都添加 url 参数,所以可以将 url 参数的值保存在 cookie 中,当没有 url 参数时,从 cookie 中取值即可,spring boot 已经通过类 org.springframework.web.servlet.i18n.CookieLocaleResolver 实现了此功能 ,并且该类实现了 org.springframework.web.servlet.LocaleResolver 接口,所以我们只需要添加 localeResolver bean 并实例化 CookieLocaleResolver 即可。 CookieLocaleResolver 通过下面两种方式获取 Locale 对象:
从 request 对象的 CookieLocaleResolver.class.getName() + ".LOCALE" 属性获取,此种方式对应有 url 参数的请求
从名为 locale(默认值) 的 cookie 中获取,此种方式对应没有 url 参数的请求
2.3 完整代码
新建类 MyMvcConfig 并实现接口 WebMvcConfigurer:
package com.sviping.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.CookieLocaleResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver(){
CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
cookieLocaleResolver.setCookieName("locale");//LocaleChangeInterceptor 默认会获取url参数 locale
return cookieLocaleResolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//多语言
registry.addInterceptor(new LocaleChangeInterceptor()).addPathPatterns("/**");
}
}2.4 测试
在浏览器中输入 localhost:8080/test?locale=en_US 后,即可切换成英文,去掉 locale 参数后,仍为英文,将参数的值改为 zh_CN 后,返回结果变为中文,到此,实现了多语言的自定义切换。
