SpringBoot实现i18n国际化配置(超详细之跟着走就会系列)

一、新增国际化资源文件

在resources文件下新建i18n文件,并新建国际化资源文件。如图:
在这里插入图片描述
点击新增Resource Bundle文件。
在这里插入图片描述
我们在Resource bundle base name处填写国际化文件的名称,笔者此处填“messages”。并点击中间偏右的“+”号,新增国际化语言,此处新增两个语言“zh_CN”,“en_US”。在这里插入图片描述
点击ok保存,看到这样的文件结构,就表示创建成功了:在这里插入图片描述
分别在两个文件中添加
zh_CN:

A00001=你好,世界
A00002=你好,JAVA

en_US:

A00001=Hello World
A00002=Hello JAVA

二、添加国际化配置

2.1 添加配置文件

spring:
  messages:
    basename: i18n/messages

注意:此处的basename填的messages是填Resource bundle base name时填的值。

2.2 添加配置类

MyLocaleResolver:

package study.dxc.resolver;

import com.alibaba.excel.util.StringUtils;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.LocaleResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

/**
 * 自定义LocaleResolver
 *
 * @author Felix.Du
 * @date: 2022/3/30 21:25
 */
@Configuration
public class MyLocaleResolver implements LocaleResolver {

    @Autowired
    private HttpServletRequest request;

    public Locale getLocal() {
        return resolveLocale(request);
    }

    /**
     * 从HttpServletRequest中获取Locale
     *
     * @param httpServletRequest    httpServletRequest
     * @return                      语言Local
     */
    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        //获取请求中的语言参数
        String language = httpServletRequest.getParameter("lang");
        //如果没有就使用默认的(根据主机的语言环境生成一个 Locale
        Locale locale = Locale.getDefault();
        //如果请求的链接中携带了 国际化的参数
        if (!StringUtils.isEmpty(language)){
            //zh_CN
            String[] s = language.split("-");
            //国家,地区
            locale = new Locale(s[0], s[1]);
        }
        return locale;
    }

    /**
     * 用于实现Locale的切换。比如SessionLocaleResolver获取Locale的方式是从session中读取,但如果
     * 用户想要切换其展示的样式(由英文切换为中文),那么这里的setLocale()方法就提供了这样一种可能
     *
     * @param request               HttpServletRequest
     * @param httpServletResponse   HttpServletResponse
     * @param locale                locale
     */
    @Override
    public void setLocale(@NonNull HttpServletRequest request, @Nullable HttpServletResponse httpServletResponse, @Nullable Locale locale) {

    }

}

添加i18n工具类,I18nUtil:

package study.dxc.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import study.dxc.resolver.MyLocaleResolver;

import javax.annotation.PostConstruct;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.Objects;

@Slf4j
@Component
public class I18nUtil {

    @Value("${spring.messages.basename}")
    private String basename;

    private final MyLocaleResolver resolver;

    private static MyLocaleResolver customLocaleResolver;

    private static String path;


    public I18nUtil(MyLocaleResolver resolver) {
        this.resolver = resolver;
    }


    @PostConstruct
    public void init() {
        setBasename(basename);
        setCustomLocaleResolver(resolver);
    }

    /**
     * 获取 国际化后内容信息
     *
     * @param code 国际化key
     * @return 国际化后内容信息
     */
    public static String getMessage(String code) {
        Locale locale = customLocaleResolver.getLocal();
        return getMessage(code, null, code, locale);
    }

    /**
     * 获取指定语言中的国际化信息,如果没有则走英文
     *
     * @param code 国际化 key
     * @param lang 语言参数
     * @return 国际化后内容信息
     */
    public static String getMessage(String code, String lang) {
        Locale locale;
        if (StringUtils.isEmpty(lang)) {
            locale = Locale.US;
        } else {
            try {
                var split = lang.split("-");
                locale = new Locale(split[0], split[1]);
            } catch (Exception e) {
                locale = Locale.US;
            }
        }
        return getMessage(code, null, code, locale);
    }

    /**
     * 获取站内信指定语言 目前只支持 中文与英文两类 默认英文
     *
     * @param code 国际化 key
     * @param lang 语言参数
     * @return 国际化后内容信息
     */
    public static String getStationLetterMessage(String code, String lang) {
        Locale locale = Objects.equals(lang, "zh-CN") ? Locale.SIMPLIFIED_CHINESE : Locale.US;
        return getMessage(code, null, code, locale);
    }


    public static String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setDefaultEncoding(StandardCharsets.UTF_8.toString());
        messageSource.setBasename(path);
        String content;
        try {
            content = messageSource.getMessage(code, args, locale);
        } catch (Exception e) {
            log.error("国际化参数获取失败===>{},{}", e.getMessage(), e);
            content = defaultMessage;
        }
        return content;

    }

    public static void setBasename(String basename) {
        I18nUtil.path = basename;
    }

    public static void setCustomLocaleResolver(MyLocaleResolver resolver) {
        I18nUtil.customLocaleResolver = resolver;
    }

}

三、测试

FirstUserController:

package study.dxc.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import study.dxc.util.I18nUtil;

import javax.servlet.http.HttpServletRequest;

@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
@Slf4j
public class FirstUserController {

    private final HttpServletRequest request;

    @GetMapping("/i18n")
    public String i18n() {
        String message1 = I18nUtil.getMessage("A00001", request.getHeader("lang"));
        String message2 = I18nUtil.getMessage("A00002", request.getHeader("lang"));
        return message1 + message2;
    }
}

因为此处截取的是请求头的lang参数,那么我们在请求的时候添加一个lang参数。
在这里插入图片描述
在这里插入图片描述
注意:此处lang传的值是zh-CN、en-US并非zh_CN、en_US,因为在MyLocaleResolver中解析参数是通过分隔符“-”解析的,而并不是“”。当然你也可以传zh_CN、en_US,只需要在MyLocaleResolver类的resolveLocale方法将解析符号换为“”即可。

  • 12
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
# i18n-demo 基于i18n利用springboot实现后台国际化demo 引入外部依赖:commons-lang3、lombok ## 背景 项目做到尾声,临时需要添加国际化内容,开始只是前台展示的页面添加了国际化支持,后来发现一些后台提示很不友好,遂也选择进行国际化处理。 ## 实现 **Springboot国际化支持的很好,我们就用自带的i18n实现国际化就行。** 1. application.properties配置文件指定messages位置 ``` spring.messages.basename=i18n.message spring.messages.encoding=UTF-8 ``` 通过查看源码我们可以知道,如果不进行配置,默认读取resource下面messages文件,源码如下: ![springboot默认国际化配置读取位置](https://img-blog.csdnimg.cn/20200511183958366.png) 2. 在resource文件夹下面创建我们配置的basename,目录结构如下图: ![三个配置文件](https://img-blog.csdnimg.cn/20200512093846448.png) **其中 message.properties必须要有,其他的配置文件命名格式为:message_语言_国家.properties**,其中语言和国家格式可以查看 java.util.Locale 类中的说明。 3. 自定义重写 LocaleResolver 类的 resolveLocale 方法,代码如下: ``` public class MyLocaleResolverConfig implements LocaleResolver { private static final String PATH_PARAMETER = "lang"; private static final String PATH_PARAMETER_SPLIT = "_"; @Override public Locale resolveLocale(HttpServletRequest request) { String lang = request.getHeader(PATH_PARAMETER); Locale locale = request.getLocale(); if (!StringUtils.isEmpty(lang)) { String[] split = lang.split(PATH_PARAMETER_SPLIT); locale = new Locale(split[0], split[1]); } return locale; } @Override public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { } } ``` resolveLocale 方法作用就是我们的程序从哪获取指定的语言信息,我这里采用的是从header中获取指定语言,如果没有则采用浏览器 默认的。 还可以从 Session 或 Cookie 中获取。**这里因为我们采取header中获取,所以前端发的请求中 Request Headers 中要有 key 为 lang,value 为 en_US 或 zh_CN 的header。** 4. 将我们自定义的 MyLocaleResolverConfig 作为 Bean 注册进系统中: ``` @Bean public LocaleResolver localeResolver() { return new MyLocale ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值