Spring Boot 实现国际化

719 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

前言

上一章讲解了Spring Boot统一接口返回和全局异常处理的时候遗留了第三个问题,不熟悉的朋友可以查看juejin.cn/post/708603… 文章,Spring Boot如何实现国际化?

实现步骤

国际化配置

在application.yml文件中添加如下配置

spring:
  messages:
    encoding: UTF-8
    baseName: i18n/messages
    fallbackToSystemLocale: false
  • basename:默认的扫描的国际化文件名为messages,即在resources建messages_xx.properties文件,多个文件可以通过逗隔开。

  • encoding:默认的编码为UTF-8。

  • cacheSeconds:加载国际化文件的缓存时间,单位为秒,默认为永久缓存。

  • fallbackToSystemLocale:当找不到当前语言的资源文件时,如果为true默认找当前系统的语言对应的资源文件如messages_zh_CN.properties,如果为false即加载系统默认的如messages.properties文件。

新增国际化文件

在resource目录下新建i18n目录,分别新建messages_en_US.properties、messages_zh_CN.properties、messages.properties文件。

注意:basename配置为:文件夹路径+文件名的前缀。

文件内容: messages_en_US.properties

user.message.validation.useridEmpty=User{0} Id is empty

messages_zh_CN.properties

user.message.validation.useridEmpty=\u7528\u6237ID{0}\u4E0D\u5B58\u5728

国际化语言解析配置

@Configuration
public class i18NConfig
{
    @Bean
    public LocaleResolver localeResolver() 
    {
        //LocaleResolver有多中实现例如session、cookie等
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.CHINA);
        return localeResolver;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() 
    {
        LocaleChangeInterceptor localeChangeInterceptor =new LocaleChangeInterceptor();
        //指定语言参数的名称,默认为为header中获取Accept-Language
        localeChangeInterceptor.setParamName("lang");
        return localeChangeInterceptor;
    }
}

//WebMvcConfigurer添加语言切换拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer
{
    @Autowired
    private LogInterceptor logInterceptor;
    
    @Autowired
    private LocaleChangeInterceptor localeChangeInterceptor;

    public void addInterceptors(InterceptorRegistry registry)
    {
        //添加语言切换拦截器
        registry.addInterceptor(localeChangeInterceptor).addPathPatterns("/**");
    
    }
}

消息工具类

@Component
public class MessageUtil
{
    @Autowired
    private MessageSource messageSource;

    public String getMessage(String code,String defaultMessage,Object[] args)
    {
        return getMessage(code,defaultMessage,args,getDefaultLocale());
    }
    
    public String getMessage(String code,Object[] args,Locale local)
    {
        return getMessage(code,null,args,local);
    }
    
    public String getMessage(String code,Object[] args)
    {
        return getMessage(code, args,getDefaultLocale());
    }
    
    public String getMessage(String code,String defaultMessage,Locale local)
    {
        return getMessage(code, defaultMessage, null,local);
    }
    
    public String getMessage(String code,Locale local)
    {
        return getMessage(code, null, null,local);
    }
    
    
    public String getMessage(String code,String defaultMessage)
    {
        return getMessage(code, defaultMessage, null,getDefaultLocale());
    }
    
    //可以动态配置默认语言
    private Locale getDefaultLocale()
    {
        return LocaleContextHolder.getLocale();
    }
    
    /**
     * 
     * @param code
     * @param defaultMessage
     * @param args
     * @param local
     * @return
     */
    public String getMessage(String code,String defaultMessage,Object[] args,Locale local)
    {
        return messageSource.getMessage(code, args, defaultMessage,local);
    }
}

示例代码

@GetMapping("getMessage")
    public String getMessage()
    {
       String messageString= messageUtil.getMessage("user.message.validation.useridEmpty",
               new String[]{"张三"},LocaleContextHolder.getLocale());
       return messageString;
    }

测试

请求http://localhost:9090/user/getMessage, 默认不带语言参数

输出结果为:

{"code":200,"data":"用户张三不存在"}
切换为英文http://localhost:9090/user/getMessage?lang=en_US 

输出结果

{"code":200,"data":"User zhangsan is empty"}

语言切换成功后,下次请求可以不需要带语言参数,切换语言时拦截器已经将语言变量进行的存储,源码内容如下:

图片.png

总结

本文讲解了SpringBoot实现后端国际化信息,由于前段的语言比较多,vue、thymeleaf、jquery每一种语言实现方式可能不同,本文就不一一讲解了,如有问题可以随时提问。