Springboot国际化信息(i18n)解析

一、介绍

1.1 国际化信息

国际化信息也称为本地化信息 。 Java 通过 java.util.Locale 类来表示本地化对象,它通过 "语言类型" 和 "国家/地区" 来创建一个确定的本地化对象 。举个例子吧,比如在发送一个具体的请求的时候,在header中设置一个键值对:"Accept-Language":"zh",通过Accept-Language对应值,服务器就可以决定使用哪一个区域的语言,找到相应的资源文件,格式化处理,然后返回给客户端。

1.2 MessageSource

Spring 定义了 MessageSource 接口,用于访问国际化信息。

复制代码
getMessage(String code, Object[] args, String defaultMessage, Locale locale)
getMessage(String code, Object[] args, Locale locale)
getMessage(MessageSourceResolvable resolvable, Locale locale)
属性 说明
code 国际化资源中的属性名。
args 传递格式化串占位符所用的运行期参数,当在资源找不到对应属性名时,会返回defaultMessage参数所指定的默认信息。
locale 表示本地化对象。
resolvable 封装了属性名、参数数组以及默认信息的大类。

二、基础使用

2.1 简单使用

在Java中,通过java.util.Locale类表示本地化对象,它通过语言类型和国家/地区等元素来确定创建一个本地化对象 。Locale对象表示具体的地理,时区,语言,政治等。我们可以通过以下方法,获取本地系统的语言,国家等信息;以及获取代表指定地区的语言,国家信息Local对象。当然你也可以调用 Locale.getAvailableLocales() 方法查看所有可用的Local对象。

java 复制代码
public class LocalTest {

    public static void main(String[] args) {
        Locale defaultLocale = Locale.getDefault();
        Locale chinaLocale = Locale.CHINA;
        Locale usLocale = Locale.US;
        Locale usLocale1 = new Locale("en", "US");
        System.out.println(defaultLocale);
        System.out.println(defaultLocale.getLanguage());
        System.out.println(defaultLocale.getCountry());
        System.out.println(chinaLocale);
        System.out.println(usLocale);
        System.out.println(usLocale1);
    }

}

结果输出

zh_CN

zh

CN

zh_CN

en_US

en_US

我们一般会将不同的语言的属性值存放在不同的配置文件中,ResourceBundle类可以根据指定的baseName和Local对象,就可以找到相应的配置文件,从而读取到相应的语言文字,从而构建出ResourceBundle对象,然后我们可以通过ResourceBundle.getString(key)就可以取得key在不同地域的语言文字了。

2.2 Properties配置

Properties配置文件命名规则:baseName_local.properties

假如baseName为i18n,则相应的配置文件应该命名为如下:

复制代码
默认的配置文件:i18n.properties
中文的配置文件:i18n_zh_CN.properties
英文的配置文件:i18n_en_US.properties

当我们这样命名生成文件后,idea也会帮我们识别这是个国际化配置包,自动转换成如下的模式:

当然变成如上模式的时候,我们再需要添加配置文件,直接在包右键new就可以了

我们也可以在如上标记的地方进行快速添加

我们通过如下方式,就可以获取相应语言环境下的信息了,如下:

java 复制代码
        chinaLocale = Locale.CHINA;
        ResourceBundle resourceBundle = ResourceBundle.getBundle("i18n", chinaLocale);
        String userName = resourceBundle.getString("userName");
        System.out.println(userName);

        usLocale = Locale.US;
        resourceBundle = ResourceBundle.getBundle("i18n", usLocale);
        userName = resourceBundle.getString("userName");
        System.out.println(userName);

输出

吴丹阳

wno704

三、springboot中的使用

3.1 服务端转码

3.1.1 服务配置

在application.yml中进行配置

yaml 复制代码
spring:
  messages:
    basename: i18n
3.1.2 编码

然后编写测试类:

java 复制代码
@RestController
public class TestResource {

    @Autowired
    private MessageSource messageSource;

    @GetMapping("test")
    public String test() {
        Locale locale = LocaleContextHolder.getLocale();
        String userName = messageSource.getMessage("userName", null, locale);
        System.out.println(userName);
        return userName;
    }
    
}
3.1.3 测试

测试如下结果:

注意:获取客户端的语言环境Locale对象,即取的请求头Accept-Language键的值来判断,我们也可以自定义请求头键,来获取语言标识。

3.2 页面语言切换

3.2.1 配置

修改 i18n.properties:

复制代码
login.password=Password
login.remember=Remember Me
login.reset=Rest
login.submit=Sign
login.username=Username

i18n_en_US.properties:

复制代码
login.password=Password
login.remember=Remember Me
login.reset=Rest
login.submit=Sign
login.username=Username

i18n_zh_CN.properties:

复制代码
login.password=密码
login.remember=记住我
login.reset=重置
login.submit=登录
login.username=用户名
3.2.2 自定义语言环境解析器

我们自定义语言环境解析器,然后在引入到WebMvc配置类中,来替代原有的语言环境解析器。我们只需要实现LocaleResolver接口即可。

java 复制代码
public class MyLocaleResolver implements LocaleResolver {

    @Override
    public Locale resolveLocale(HttpServletRequest httpServletRequest) {
        //获取请求中的语言参数
        String language = httpServletRequest.getParameter("l");
        Locale locale = Locale.getDefault();//如果没有就是用默认的
        //如果请求的连接携带了国际化的参数
        if (!StringUtils.isEmpty(language)){
            //zh-CN
            String[] split = language.split("_");
            //国家,地区
            locale = new Locale(split[0], split[1]);
        }
        return locale;
    }

    @Override
    public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
    }

}

将自定义的语言环境解析器,加入SpringMvc自动配置类中

在自动配置类中需要将自定义的MyLocaleResolver类取代WebMvcAutoConfiguration中对应的方法

java 复制代码
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("login");
    }

    //自定义国际化组件就生效了
    @Bean
    public LocaleResolver localeResolver() {
        return new MyLocaleResolver();
    }

}
3.2.3 编写测试页面

首先需要引入

xml 复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

然后编写测试页面controller

java 复制代码
@Controller
public class LoginController {

    @RequestMapping("/login")
    public String index() {
        return "login";
    }

}

编写测试页面 login.hrml

html 复制代码
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>[[#{login.title}]]</title>
    <link rel="stylesheet" th:href="@{/css/login.css}" type="text/css">
</head>
<body>
<div class="login-page">
    <div class="form">
        <span>[[#{login.title}]]</span>
        <hr/>
        <input type="text" th:placeholder="#{login.username}" name="username" required="required"/>
        <input type="password" th:placeholder="#{login.password}" name="password" required="required"/>
        <button onclick="login()" th:text="#{login.submit}"></button>
        <button onclick="login()" th:text="#{login.reset}"></button>
        <div style="margin-left: 100px;">
            <a href="#" th:href="@{/login(l='zh_CN')}">中文</a>
            <a href="" th:href="@{/login(l='en_US')}">English</a>
        </div>
    </div>
</div>
</body>
</html>

测试如下结果:

浏览器打开:http://127.0.0.1:8080/login

点击English切换英文

相关推荐
eleven_4u1 小时前
QPS如何计算,如何部署架构
java·linux·运维·jvm·中间件
牧瀬クリスだ1 小时前
Redis Hash实战:高效存储对象与购物车
java·数据库·redis·算法·哈希算法
文丑颜不良啊1 小时前
LeetCode1141~1160题目解析
java·leetcode
木井巳1 小时前
【动态规划: 路径问题】下降路径最小和
java·算法·leetcode·动态规划·推荐算法
秋饼1 小时前
MySQL 分库分表完全指南:ShardingSphere-JDBC 实战、分片键选型、场景边界、20 个生产坑与 30 道面试点
java·mysql·面试·shardingsphere·分库分表·后端架构
郭小李2 小时前
spring 的 @CookieValue 注解 用法
java·后端·spring
天远Date Lab2 小时前
零信任架构实战:基于天远企业股权变更构建自动化招投标供应商股东穿透审查网关
java·人工智能·架构·自动化
god_cvz2 小时前
麒麟 V10(ARM64 / aarch64)源码编译 3dtiles 全步骤
后端·gis
武子康2 小时前
批量设备任务显示 COMPLETED,为什么还有设备失败?
人工智能·后端·agent