现在都是前后端分离开发,那么我们如何处理接口的国际化呢?直接入主题
- 在resources目录下建一个i18n目录
- 在这个目录里创建一个Resource Bundle, BaseName叫messages, 选择需要国际化的语言,我选择了zh_CN, en_US
- 在对应的messages_zh_CN.properties中翻译好内容(key value的形式)
- 在application.yml中配置一下,Spring Boot会根据该配置来生成ReloadableResourceBundleMessageSource的对象messageSource
spring:
basename: i18n/messages
encoding: UTF-8
配置就差不多了,这儿我说一下国际化处理的原理,就是接口中通知服务器客户端需要什么语言的内容,服务器就根据客户端的需求来读取对应的properties中的内容。 通知服务器有两种方式,第一种就是参数的方式通知,第二中就是http header中的参数来通知。 Spring Boot为我们提供了这两种的处理方式。
我们先说第一种,通过参数的方式,比如http://xxxx/api/login?lang=zh_CN
配置一下MVC
@Configuration
public class WebMVCConfiguration implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver acceptHeaderLocaleResolver = new SessionLocaleResolver();
acceptHeaderLocaleResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return acceptHeaderLocaleResolver;
}
private LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("lang");
return localeChangeInterceptor;
}
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
给每一个请求加一个中间件,用来检查lang参数,并更具该参数的值来设置Locale
第二种就是根据Http Header中的accept-language来设置Locale
就是配置一个locale解析器
@Bean
public LocaleResolver localeResolver() {
AcceptHeaderLocaleResolver acceptHeaderLocaleResolver = new AcceptHeaderLocaleResolver();
acceptHeaderLocaleResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
return acceptHeaderLocaleResolver;
}
这种方式有一个问题,Accept-Language的值一定要加用zh-CN或en-US,否则设置会失败的哦。我开始传的就是zh_CN与en_US, 结果死活不行, 后来跟踪代码慢慢发现这个问题的解决方法。
接下来我看如何获取properties中的值,定义一个I18nService的类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import java.util.Locale;
@Service
public class I18nService {
@Autowired
private MessageSource messageSource;
public I18nService(MessageSource messageSource) {
this.messageSource = messageSource;
}
public String getMessage(String msgKey, Object[] args) {
return messageSource.getMessage(msgKey, args, LocaleContextHolder.getLocale());
}
public String getMessage(String msgKey) {
Locale locale = LocaleContextHolder.getLocale();
return messageSource.getMessage(msgKey, null, locale);
}
}
在Controller或Service使用这个类
@Autowired
private I18nService i18nService;
String str = i18nService.getMessage("message.key.test");
好了,国际化就完成了,不懂的留言套路哦。
网友评论