国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现

背景

最近项目要做国际化,所以就简单调研了下国际化的实现,发现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=小奏
国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现
在这里插入图片描述

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: 函数式接口,对上面参数的封装国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现
  • 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国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现
  • zh国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现这里可以看到我们通过不同的Accept-Language获取到了不同的语言信息

自定义切换参数

实际我们有时候前端可能会通过自定义个参数传入语言环境,所以我们也可以自定义参数来设置语言环境,比如我们通过paramlang值来设置

这里我们需要添加配置

  • 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

我们再重试试试国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现传入参数lang = en试试国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现可以看到成功了

参数校验国际化

我们在使用一些错误提示的使用希望也能够支持国际化,要实现该需求如何处理呢?

  1. 添加校验依赖
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-validation</artifactId>
  </dependency>
  1. 添加校验国际化配置
@Bean
 public Validator getValidator(MessageSource messageSource) {
  LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
  bean.setValidationMessageSource(messageSource);
  return bean;
 }

注意该ValidatorSpring国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现org.springframework.validation.Validator不支持,不要导错包国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现3. 全局异常处理

  • 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);
 }
 
}
  1. 编写校验类
@Data
public class User {

 @NotEmpty(message = "{email.notempty}")
 private String email;

}

注意这里的错误提示是读取我们的国际化配置文件

  1. 国际化配置添加错误提示key
  • messages_en.properties
email.notempty=Please provide valid email id.
  • messages_zh.properties
email.notempty=邮箱不能为空
  1. 测试 我们这里还是使用上面的controller改改
 @GetMapping("/international")
 public String getInternationalPage(@Valid User user) {
  return messageSource.getMessage("user.name"null, LocaleContextHolder.getLocale());
 }

测试效果国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现

  • en国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现

乱码问题

如果文件乱码需要如下可能需要设置idea file文件编码格式国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现

这里设置为UTF-8即可

总计

总的来说Spring 对国际化支持还是比较友好的,但是实际线上使用可能还是需要更多的二次开发

参考

  • spring-boot-internationalization


原文始发于微信公众号(小奏技术):国际化(i18)不知道怎么做?来看看利用Spring Boot如何优雅实现

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/29785.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!