SpringBoot 多语言 – 国际化 – i18n

2024-06-16 00:28:46 浏览数 (2)

本页目录

  • 了解多语言的3大对象
    • LocaleResolver介绍
    • Locale对象
    • MessageSource对象
  • 实操多语言
    • 创建对语言的配置文件
    • 添加application.properties配置文件
    • 编写代码测试
    • 请求测试:修改 请求头:Accept-Language

SpringBoot对多语言也是支持的。实现多语言我们关注3个对象

  • LocaleResolver接口
  • Locale对象
  • MessageSource对象

快速小结:LocaleResolver接口的实现类获得Locale对象,Locale对象告诉MessageSource从哪个配置文件获得消息!

了解多语言的3大对象

LocaleResolver介绍

LocaleResolver 是 Spring Framework 中的一个接口,用于解析客户端请求的区域信息(Locale),即确定用户的语言和国家/地区偏好。它的主要作用是根据请求的信息确定应该使用哪种语言和区域设置来呈现用户界面。

白话就是:解析到底用哪种Locale对象。Spring也封装了一些

  1. AcceptHeaderLocaleResolver
    • 根据 HTTP 请求头的 Accept-Language 头部信息来解析 Locale。它会尝试从请求的头部信息中获取客户端的首选语言设置。
  2. CookieLocaleResolver
    • 根据一个特定的 cookie 中存储的 Locale 信息来解析。如果用户曾经选择过语言偏好,该信息会存储在 cookie 中,以便后续请求可以保持一致的语言设置。
  3. SessionLocaleResolver
    • 根据用户当前的会话(session)中存储的 Locale 信息来解析。它适合于需要在用户会话期间保持一致语言设置的应用程序。
  4. FixedLocaleResolver
    • 一个固定的 LocaleResolver 实现,它始终返回预定义的固定 Locale。这在调试和特定测试场景中可能会有用。

Locale对象

Locale 对象代表了一个特定的地区和语言的组合。它通常由语言标识符(如 enzh_CN)来表示,Spring Boot 中通过 LocaleResolver 解析得到的 Locale 对象将决定应用程序在用户界面中显示哪种语言和格式。

白话就是:给MessageSource对象告诉它,用哪个语言?

MessageSource对象

MessageSource 是 Spring Framework 提供的国际化消息解析器接口,它负责加载不同语言环境下的消息资源。在 Spring Boot 中,通常使用 ResourceBundleMessageSource 或者 ReloadableResourceBundleMessageSource 来加载属性文件(.properties 文件),这些文件包含了不同语言对应的消息文本。通过 MessageSource,可以根据 Locale 对象获取到对应语言的消息文本,从而实现应用程序界面的多语言支持。

白话就是:MessageSource是用来获取消息的

实操多语言

创建对语言的配置文件

代码语言:javascript复制
resource文件夹放置
├── i18n
│   ├── msg.properties
│   ├── msg_en.properties
│   └── msg_zh.properties

msg.properties

代码语言:javascript复制
INFO=我是默认的配置
NOT_NULL={0}不得为空

msg_en.properties

代码语言:javascript复制
INFO=我是英文的配置
NOT_NULL={0} not be null

msg_zh.properties

代码语言:javascript复制
INFO=我是中文的配置
NOT_NULL={0}不得为空

添加application.properties配置文件

目的是制定我们的多语言包路径

代码语言:javascript复制
# 以逗号分隔的基名称列表(本质上是一个完全限定的类路径位置),每个基名称都遵循ResourceBundle约定,并轻松支持基于斜杠的位置。如果它不包含包限定符(如“org. mypackage”),它将从类路径根解析
spring.messages.basename=i18n.msg

编写代码测试

代码语言:javascript复制
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;

/**
 * @author : zanglikun
 * @date : 2024/6/15 下午10:29
 * @desc : Copyright © zanglikun.com
 */
@Api(tags = "多语言")
@RestController
@RequestMapping("/test/api/v1/")
public class I18nController {

    @Resource
    // 获得多语言对象
    private MessageSource messageSource;

    @Resource
    // 使用此对象来动态解析请求头中的 Accept-Language,以达到动态切换多语言的目的
    private AcceptHeaderLocaleResolver localeResolver;


    @ApiOperation("测试多语言消息")
    @GetMapping("/getI18n")
    public String testI18nMessage(HttpServletRequest request) {
        // 从spring.messgae.basename=i18n.msg 去resource文件夹下照 i18n/msg.properties文件的 NOT_NULL 信息
        String info = messageSource.getMessage("NOT_NULL", null, Locale.getDefault());

        // 获得动态的Locale对象
        Locale dynamicLocale = localeResolver.resolveLocale(request);
        String[] args = new String[]{"id"};
        String dynamicInfo = messageSource.getMessage("NOT_NULL", args, dynamicLocale);
        return dynamicInfo;
    }
}

请求测试:修改 请求头:Accept-Language

en-US

代码语言:javascript复制
curl --location --request GET 'http://127.0.0.1:8089/test/api/v1/getI18n' 
--header 'Accept: */*' 
--header 'Accept-Language: en-US' 
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)'

输出:id not be null

zh-CN

代码语言:javascript复制
curl --location --request GET 'http://127.0.0.1:8089/test/api/v1/getI18n' 
--header 'Accept: */*' 
--header 'Accept-Language: zh-CN' 
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)'

输出:id不得为空

上文只是一个示例:如果你需要更多的花样,比如在全局抛异常的时候,你可以在全局的拦截器上,使用这个多语言处理你要输出给前端的错误信息。

或者在处理跟前端约定的语言标记,可以实现LocaleResolver来获得Locale对象!

经过Mybatis友友们交流。请求头填什么的时候,发现:有的说是zh-cn 有的是zh_ch。

在 Accept-Language HTTP 头部中,语言标签的格式是由 RFC 5646 定义的,这是一种标准的语言标签格式,用于指定用户的语言偏好。RFC 5646 标准规定,语言标签由一个主语言代码(例如 zh 表示中文)和一个可选的国家/地区代码(例如 CN 表示中国)组成,二者之间用连字符 - 分隔,如 zh-CN

至于 zh_cn 或其他类似形式,这些并不符合 RFC 5646 标准定义的语言标签格式。浏览器在设置 Accept-Language 头部时,通常会遵循 RFC 5646 标准来生成语言标签,以确保与服务器的语言协商可以顺利进行,同时尽可能精确地表达用户的语言偏好。

因此,正确的方式是使用 zh-CN 这种格式来表示简体中文,而不是 zh_cn。服务器端应该按照 RFC 5646 标准解析 Accept-Language 头部,以获得正确的语言偏好信息,并根据需要来提供相应的语言版本内容给用户。

不过语言你可以参考:我们常见的ISO639-1:https://www.andiamo.co.uk/resources/iso-language-codes/

特殊说明: 上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com 第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取全部资料 ❤

0 人点赞