i18n国际化-springboot整合

简介

i18n(其来源是英文单词internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称。在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无需做大的改变就能够适应不同的语言和地区的需要。对程序来说,在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面。在全球化的时代,国际化尤为重要,因为产品的潜在用户可能来自世界的各个角落。通常与i18n相关的还有L10n(“本地化”的简称)。。

springboot项目整合国际化

application.yml文件配置

# Spring配置
spring:
  # 资源信息
  messages:
    # 国际化资源文件路径
    basename: i18n/messages
    encoding: utf-8

ps: basename配置为项目的多语言资源文件地址,如下图所示,多语言文件命名规则为:资源名称_语言_国家/地区
在这里插入图片描述

工具类

public class MessageUtils
{
    /**
     * 根据消息键和参数 获取消息 委托给spring messageSource
     * 适用场景,系统全局语言
     * @param code 消息键
     * @param args 参数   用于填充消息中的参数(消息中的参数看起来像“{0}”,“{1,date}”,“{2,time}”)
     * @return 获取国际化翻译值
     */
    public static String message(String code, Object... args)
    {
        MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
        return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
    }

    /**
     * 根据消息键和参数 获取消息 委托给spring messageSource 指定特定语言
     * @param code 消息键
     * @param locale 使用的语言eg:ENGLISH
     * @param args 参数
     * @return 获取国际化翻译值
     */
    public static String message(String code, Locale locale, Object... args)
    {
        MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
        return messageSource.getMessage(code, args, locale);
    }
}
/**
 * spring工具类 方便在非spring管理环境中获取bean
 * 
 * @author ruoyi
 */
@Component
public final class SpringUtils implements BeanFactoryPostProcessor
{
    /** Spring应用上下文环境 */
    private static ConfigurableListableBeanFactory beanFactory;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
    {
        SpringUtils.beanFactory = beanFactory;
    }

    /**
     * 获取对象
     *
     * @param name
     * @return Object 一个以所给名字注册的bean的实例
     * @throws org.springframework.beans.BeansException
     *
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) throws BeansException
    {
        return (T) beanFactory.getBean(name);
    }

    /**
     * 获取类型为requiredType的对象
     *
     * @param clz
     * @return
     * @throws org.springframework.beans.BeansException
     *
     */
    public static <T> T getBean(Class<T> clz) throws BeansException
    {
        T result = (T) beanFactory.getBean(clz);
        return result;
    }

    /**
     * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
   

国际化拦截器配置

@Configuration
public class I18nConfig {

    @Bean
    public LocaleResolver localeResolver()
    {
        SessionLocaleResolver slr = new SessionLocaleResolver();
        // 默认语言
        slr.setDefaultLocale(Locale.CHINA);
        return slr;
    }

    /**
     * header拦截器 其中lang表示切换语言的参数名
     * 在spring boot2.0 之后 通过继承WebMvcConfigurer类 就可以完成拦截
     * 在这里他直接返回了一个覆写了addInterceptors方法的WebMvcConfigurer匿名对象
     * 以十分简洁的方式达成了他的目的
     */
    @Bean
    public WebMvcConfigurer i18nInterceptor() {
        return new WebMvcConfigurer() {
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                //默认拦截器:请求国际化参数为?lang=en_us
                //LocaleChangeInterceptor i18nInterceptor = new LocaleChangeInterceptor();
                //自定义header拦截器,请求参数在header中添加lang的键值
                LocaleChangeInterceptor i18nInterceptor = new HeaderLocaleChangeInterceptor();
                i18nInterceptor.setParamName("lang");
                registry.addInterceptor(i18nInterceptor).addPathPatterns("/**");
            }
        };
    }
}

自定义拦截器

/**
 * i18n拦截器:从请求头获取国际化参数
 * @author Leoz
 * @date 2021/9/29 17:07
 */
public class HeaderLocaleChangeInterceptor extends LocaleChangeInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException {
        //从请求头获取国际化参数
        String newLocale = request.getHeader(this.getParamName());
        if (newLocale != null && this.checkHttpMethod(request.getMethod())) {
            LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
            if (localeResolver == null) {
                throw new IllegalStateException("No LocaleResolver found: not in a DispatcherServlet request?");
            }

            try {
                localeResolver.setLocale(request, response, this.parseLocaleValue(newLocale));
            } catch (IllegalArgumentException var7) {
                if (!this.isIgnoreInvalidLocale()) {
                    throw var7;
                }

                this.logger.debug("Ignoring invalid locale value [" + newLocale + "]: " + var7.getMessage());
            }
        }
        return true;
    }

    private boolean checkHttpMethod(String currentMethod) {
        String[] configuredMethods = this.getHttpMethods();
        if (ObjectUtils.isEmpty(configuredMethods)) {
            return true;
        } else {
            String[] var3 = configuredMethods;
            int var4 = configuredMethods.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                String configuredMethod = var3[var5];
                if (configuredMethod.equalsIgnoreCase(currentMethod)) {
                    return true;
                }
            }

            return false;
        }
    }
}

测试

    @RestController
    class Test {

        @RequestMapping("/test")
        public String test() {
            String message = MessageUtils.message("test");
            return message;
        }
    }

在messages.properties中添加内容:test=測試
在messages_en_US.properties中添加内容:test=test

postman请求结果

在这里插入图片描述
在这里插入图片描述
这里国际化整合完成
注意:如果没有找到对应的语言将会采用默认语言展示,这里是messages.properties
更多语言格式参考 java.util.Locale类


    /** Useful constant for language.
     */
    static public final Locale ENGLISH = createConstant("en", "");

    /** Useful constant for language.
     */
    static public final Locale FRENCH = createConstant("fr", "");

    /** Useful constant for language.
     */
    static public final Locale GERMAN = createConstant("de", "");

    /** Useful constant for language.
     */
    static public final Locale ITALIAN = createConstant("it", "");

    /** Useful constant for language.
     */
    static public final Locale JAPANESE = createConstant("ja", "");

    /** Useful constant for language.
     */
    static public final Locale KOREAN = createConstant("ko", "");

    /** Useful constant for language.
     */
    static public final Locale CHINESE = createConstant("zh", "");

    /** Useful constant for language.
     */
    static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");

    /** Useful constant for language.
     */
    static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");

    /** Useful constant for country.
     */
    static public final Locale FRANCE = createConstant("fr", "FR");

    /** Useful constant for country.
     */
    static public final Locale GERMANY = createConstant("de", "DE");

    /** Useful constant for country.
     */
    static public final Locale ITALY = createConstant("it", "IT");

    /** Useful constant for country.
     */
    static public final Locale JAPAN = createConstant("ja", "JP");

    /** Useful constant for country.
     */
    static public final Locale KOREA = createConstant("ko", "KR");

    /** Useful constant for country.
     */
    static public final Locale CHINA = SIMPLIFIED_CHINESE;

    /** Useful constant for country.
     */
    static public final Locale PRC = SIMPLIFIED_CHINESE;

    /** Useful constant for country.
     */
    static public final Locale TAIWAN = TRADITIONAL_CHINESE;

    /** Useful constant for country.
     */
    static public final Locale UK = createConstant("en", "GB");

    /** Useful constant for country.
     */
    static public final Locale US = createConstant("en", "US");

    /** Useful constant for country.
     */
    static public final Locale CANADA = createConstant("en", "CA");

    /** Useful constant for country.
     */
    static public final Locale CANADA_FRENCH = createConstant("fr", "CA");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值