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

发布于:2023-01-09 ⋅ 阅读:(486) ⋅ 点赞:(0)

这里是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获取到了不同的语言信息

自定义切换参数

实际我们有时候前端可能会通过自定义个参数传入语言环境,所以我们也可以自定义参数来设置语言环境,比如我们通过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

我们再重试试试
在这里插入图片描述
传入参数lang = en试试
在这里插入图片描述
可以看到成功了

参数校验国际化

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

  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
在这里插入图片描述
org.springframework.validation.Validator不支持,不要导错包
在这里插入图片描述

issues连接

  1. 全局异常处理
  • 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());
	}

测试效果
在这里插入图片描述

  • en
    在这里插入图片描述

乱码问题

如果文件乱码需要如下可能需要设置idea file文件编码格式
在这里插入图片描述

这里设置为UTF-8即可

总计

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

参考


网站公告

今日签到

点亮在社区的每一天
去签到