大家好,欢迎来到IT知识分享网。
这里是weihubeats,觉得文章不错可以关注公众号小奏技术,文章首发。拒绝营销号,拒绝标题党
背景
最近项目要做国际化,所以就简单调研了下国际化的实现,发现Spring Boot
本身就对国际化有支持,所以这里就对Spring Boot
的国际化做了一下简单的调研使用,发现还是挺好用的
这里补充下一个小知识,为什么国际化都叫i18
,因为国际化英文是internationalization
,在 i 和 n 之间有 18 个字母,所以叫i18n
maven依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
这里Spring Boot版本的2.6.8
创建国际化配置文件
- messages.properties
user.name=default-name
- messages_en.properties
user.name=xiaozou
- messages_zh.properties
user.name=小奏
MessageSource
Spring Boot
负责国际化的核心接口是MessageSource
,我们来看看MessageSource
接口的方法
@Nullable String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale); String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException; String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
这里提供了getMessage
的三个重载方法,我们介绍下不同参数的作用
String code
: 待解析的字符串Object[] args
: 待解析字符串的参数,可以基于 MessageFormat 解析带有 占位符 的字符串String defaultMessage
: 读取不到 国际化 信息时返回的默认值MessageSourceResolvable resolvable
: 函数式接口,对上面参数的封装Locale locale
: 国际化定位
创建Controller测试
@RestController @RequestMapping public class TestController {
@Autowired MessageSource messageSource; @GetMapping("/international") public String getInternationalPage() {
return messageSource.getMessage("user.name", null, LocaleContextHolder.getLocale()); } }
这里我们在application.yaml
设置一下编码格式为UTF-8
防止乱码
spring: messages: encoding: UTF-8
这里我们通过设置不同的语言来获取user.name
的值
这里需要注意Spring 默认设置当前语言是通过请求头的Accept-Language
来配置当前的环境
,然后语言与配置文件去做匹配
比如传入的语言是en
,就会使用messages_en.properties
,我们这里来简单测试一下
- en
- zh
这里可以看到我们通过不同的Accept-Language
获取到了不同的语言信息
自定义切换参数
实际我们有时候前端可能会通过自定义个参数传入语言环境,所以我们也可以自定义参数来设置语言环境,比如我们通过param
的lang
值来设置
这里我们需要添加配置
- WebMvcConfig
@Configuration public class WebMvcConfig implements WebMvcConfigurer {
@Override public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor()); } @Bean public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); lci.setParamName("lang"); return lci; } @Bean public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver(); // 设置默认环境 slr.setDefaultLocale(Locale.SIMPLIFIED_CHINESE); return slr; } }
这里我们设置默认的环境为zh
我们再重试试试
传入参数lang = en
试试
可以看到成功了
参数校验国际化
我们在使用一些错误提示的使用希望也能够支持国际化,要实现该需求如何处理呢?
- 添加校验依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
- 添加校验国际化配置
@Bean public Validator getValidator(MessageSource messageSource) {
LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean(); bean.setValidationMessageSource(messageSource); return bean; }
注意该Validator
非Spring
的
org.springframework.validation.Validator
不支持,不要导错包
issues连接
- 全局异常处理
- GlobalExceptionHandler
@RestControllerAdvice @Configuration(proxyBeanMethods = false) @Slf4j public class GlobalExceptionHandler {
@ExceptionHandler(BindException.class) public String exceptionHandle(Exception e) {
String message = e.getMessage(); return message.substring(message.lastIndexOf("default message") + 15); } }
- 编写校验类
@Data public class User {
@NotEmpty(message = "{email.notempty}") private String email; }
注意这里的错误提示是读取我们的国际化配置文件
- 国际化配置添加错误提示key
- messages_en.properties
email.notempty=Please provide valid email id.
- messages_zh.properties
email.notempty=邮箱不能为空
- 测试
我们这里还是使用上面的controller改改
@GetMapping("/international") public String getInternationalPage(@Valid User user) {
return messageSource.getMessage("user.name", null, LocaleContextHolder.getLocale()); }
测试效果
- en
乱码问题
如果文件乱码需要如下可能需要设置idea file文件编码格式
这里设置为UTF-8
即可
总计
总的来说Spring 对国际化支持还是比较友好的,但是实际线上使用可能还是需要更多的二次开发
参考
- spring-boot-internationalization
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/157623.html