SpringBoot i18n 配置

发布时间 2023-05-29 22:12:25作者: 伊文小哥

概述

由于项目需要进行国际化提示,所以做了一下SpringBoot的 i18n 的配置。有两种方式实现 i18n 的配置操作

  1. 页面每次访问后端都携带用户设定的语言类型的 i18n 国际化操作。在请求URL中设置一个字段 ?language=zh_CN 的方式实现或者请求头中设置表明语言类型都行Accept-Language: zh_CN
  2. 页面不能每次都携带用户设定的语言类型,则需要一张User表的字段language来保存用户设定的语言来进行国际化操作。主要实现思路是:User表中的新增字段 language采用字符串保存 i18n 国家语言格式(即 zh_CN、en_US等),如果用户没有指定语言时,默认为 zh_CN即可。当用户每次进行切换语言时即可进行更新或者新增操作。还可以新增一个表用于保存 i18n 的国际化内容,通过SQL的方式进行国际化设置操作也行,这样就可以不用每次都要修改或者新增配置文件再发版了----思路简单就不做演示了

实现方式

在请求URL中设置一个字段 ?language=zh_CN 的方式实现或者请求头中设置语言类型都行Accept-Language: zh_CN

新增国际化文件

在Spring Boot中国际化文件的名称默认为messages。在resources文件夹下新建一个i18n文件夹,在 i18n文件夹中依次新建messages.propertiesmessages_en_US.propertiesmessages_zh_CN.propertiesmessages_zh_TW.properties四个文件。其中messages.properties表示默认的,里面可以没有值,但必须有这样的一个文件,其他三个分别对应英文、中文简体、中文繁体。新建方式如下两图


添加配置文件设置

配置国际化文件所在的位置以及编码格式

spring:
  web:
    #设置本地语言为zh_CN
    locale: zh_CN
  messages:
    #在i18n文件下message开头的配置文件
    basename: i18n/messages
    #配置缓存的时间,单位 s
    cache-duration: 10
    #指定编码格式
    encoding: UTF-8

配置解析器

设置当前会话的默认国际化语言:初始化LocaleResolver类(该类为默认的解析器)

@Configuration
public class LocaleConfiguration {

    /**
     * 配置默认解析器。其中Locale.CHINA表示默认语言为简体中文
     */
    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.CHINA);

        return localeResolver;
    }
}

配置拦截器

通过拦截器来对请求的语言参数进行获取,采用默认的LocaleChangeInterceptor作为拦截器,用于指定切换国际化语言的参数名。比如当请求的URL中包含?lang=zh_CN表示读取国际化文件 messages_zh_CN.properties

@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    /**
     * 默认的拦截器,其中language表示要切换语言的参数名
     *
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
        localeInterceptor.setParamName("language");
        
        registry.addInterceptor(localeInterceptor);
    }
}

添加i18n工具类

@Component
public class MessageUtils {

    private static MessageSource messageSource;

    public MessageUtils(MessageSource messageSource) {
        MessageUtils.messageSource = messageSource;
    }

    /**
     * 指定语言获得单个国际化翻译值
     * @param msgKey    国际化文件key值
     * @param language  语言,格式 zh_CN
     * @param args      其他参数,可为null
     */
    public static String getMsgValueByLanguage(String msgKey, String language, Object... args) {
        String[] localeArgs = language.split(Constant.CONNECTOR);
        Locale locale = new Locale(localeArgs[0],localeArgs[1]);
        
        return messageSource.getMessage(msgKey, args, locale);
    }
}

测试

@RestController
@RequestMapping("/i18n")
public class I18nController {

    @RequestMapping("/user")
    public String getUserName() {
        String username = MessageUtils.get("username");
        System.out.println(username);
        return username;
    }
}
  1. 访问 http://localhost:8080/i18n/user 获取的是默认的messages.properties的国际化值
  2. 访问 http://localhost:8080/i18n/user?language=en_US 获取的是默认的messages_en_US.properties的国际化值