Spring Boot做国际化

简介: Spring Boot做国际化

一、什么是国际化

国际化,也叫 i18n,为啥叫这个名字呢?因为国际化英文是 internationalization ,在 i 和 n 之间有 18 个字母,所以叫 i18n。我们的应用如果做了国际化就可以在不同的语言环境下,方便的进行切换,最常见的就是中文和英文之间的切换,国际化这个功能也是相当的常见。

二、基本使用

Spring Boot 对于国际化的支持,默认是通过 AcceptHeaderLocaleResolver 解析器来完成的,这个解析器,默认是通过请求头的 Accept-Language 字段来判断当前请求所属的环境的,进而给出合适的响应。

所以在 Spring Boot 中做国际化,这一块我们可以不用配置。直接使用,首先创建一个普通的 Spring Boot 项目,添加 web 依赖即可。项目创建成功后,默认的国际化配置文件放在 resources 目录下,所以我们直接在该目录下创建四个测试文件,如下:

说明:

a、我们的 message 文件是直接创建在 resources 目录下的,IDEA 在展示的时候,会多出一个 Resource Bundle,这个大家不用管,千万别手动去创建这个目录。

b、messages.properties 这个是默认的配置,其他的则是不同语言环境下的配置,en_US 是英语(美国),zh_CN 是中文简体,zh_TW 是中文繁体(文末附录里边有一个完整的语言简称表格)

四个文件创建好之后,第一个默认的我们可以先空着,另外三个分别填入以下内容:

messages_zh_CN.properties

user.name=点点你好

messages_zh_TW.properties

user.name=點點你好

messages_en_US.properties

user.name=hello diandian

配置完成后,我们就可以直接开始使用了。在需要使用值的地方,直接注入 MessageSource 实例即可。

在 Spring 中需要配置的 MessageSource 现在不用配置了,Spring Boot 会通过 org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration 自动帮我们配置一个 MessageSource 实例。

@RestController
public class HelloController {
    @Autowired
    MessageSource messageSource;
    @GetMapping("/hello")
    public String hello() {
        return messageSource.getMessage("user.name", null, LocaleContextHolder.getLocale());
    }
}

在 HelloController 中我们可以直接注入 MessageSource 实例,然后调用该实例中的 getMessage 方法去获取变量的值,第一个参数是要获取变量的 key,第二个参数是如果 value 中有占位符,可以从这里传递参数进去,第三个参数传递一个 Locale 实例即可,这相当于当前的语言环境。

接下来我们就可以直接去调用这个接口了。

默认情况下,在接口调用时,通过请求头的 Accept-Language 来配置当前的环境,我这里通过 POSTMAN 来进行测试,改变Accept-Lanaguage得到不同语言内容

三、自定义切换

切换参数放在请求头里边好像不太方便,那么也可以自定义解析方式。例如参数可以当成普通参数放在地址栏上或者链接,常见得语言切换

Thymeleaf页面中使用Message表达式从国际化配置文件中取值,

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">
    <title>Signin Template for Bootstrap</title>
    <!-- Bootstrap core CSS -->
    <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
    <!-- Custom styles for this template -->
    <link th:href="@{/css/signin.css}" rel="stylesheet">
  </head>
 
  <body class="text-center">
    <form class="form-signin" action="dashboard.html">
      <img class="mb-4" th:src="@{/img/bootstrap-solid.svg}" alt="" width="72" height="72">
      <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}">Please sign in</h1>
      <input type="text" class="form-control" th:placeholder="#{login.Username}" required="" autofocus="">
      <input type="password" class="form-control" th:placeholder="#{login.password}" required="">
      <div class="checkbox mb-3">
        <label>
          <input type="checkbox" value="remember-me"> [[#{login.remember}]]
        </label>
      </div>
      <button class="btn btn-lg btn-primary btn-block" type="submit">[[#{login.sign}]]</button>
      <p class="mt-5 mb-3 text-muted">© 2017-2018</p>
      <a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
      <a class="btn btn-sm" th:href="@{/index.html(l='en_Us')}">English</a>
    </form>
 
  </body>
 
</html>

方式一:

自定义一个国际化组件

 
import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
 
 
//国际化解析器
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) {
 
    }
}
 

还需要写一个配置文件来表明国际化解析器是用的我们自己写的

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
  @Bean
    public LocaleResolver localeResolver(){
        return new MyLocaleResolver();
    }
}

方式二:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
        interceptor.setParamName("lang");
        registry.addInterceptor(interceptor);
    }
    @Bean
    LocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
        return localeResolver;
    }
}

 

在这段配置中,我们首先提供了一个 SessionLocaleResolver 实例,这个实例会替换掉默认的 AcceptHeaderLocaleResolver,不同于 AcceptHeaderLocaleResolver 通过请求头来判断当前的环境信息,SessionLocaleResolver 将客户端的 Locale 保存到 HttpSession 对象中,并且可以进行修改(这意味着当前环境信息,前端给浏览器发送一次即可记住,只要 session 有效,浏览器就不必再次告诉服务端当前的环境信息)。

另外我们还配置了一个拦截器,这个拦截器会拦截请求中 key 为 lang 的参数(不配置的话是 locale),这个参数则指定了当前的环境信息。

我们通过在请求中添加 lang 来指定当前环境信息。这个指定只需要一次即可,也就是说,在 session 不变的情况下,下次请求可以不必带上 lang 参数,服务端已经知道当前的环境信息了。

四、自定义配置

默认情况下,我们的配置文件放在 resources 目录下,如果大家想自定义,也是可以的,例如定义在 resources/i18n 目录下:

但是这种定义方式系统就不知道去哪里加载配置文件了,此时还需要 application.properties 中进行额外配置(注意这是一个相对路径):

spring.messages.basename=i18n/messages

国际化配置文件前缀名为message时,SpringBoot会自动加载。我们也可以自己定义国际化文件名称,这里我们将国际化配置文件命名为login

spring.messages.basename=i18n/login

其他配置

spring.messages.cache-duration=3600
spring.messages.encoding=UTF-8
spring.messages.fallback-to-system-locale=true

spring.messages.cache-duration 表示 messages 文件的缓存失效时间,如果不配置则缓存一直有效。

spring.messages.fallback-to-system-locale在找不到当前系统对应的资源文件时,如果该属性为 true,则会默认查找当前系统对应的资源文件,否则就返回 null,返回 null 之后,最终又会调用到系统默认的 messages.properties 文件。

五、附录

语言简称表

语言    简称

简体中文(中国)    zh_CN

繁体中文(中国台湾)    zh_TW

繁体中文(中国香港)    zh_HK

英语(中国香港)    en_HK

英语(美国)    en_US

英语(英国)    en_GB

英语(全球)    en_WW

英语(加拿大)    en_CA

英语(澳大利亚)    en_AU

英语(爱尔兰)    en_IE

英语(芬兰)    en_FI

芬兰语(芬兰)    fi_FI

英语(丹麦)    en_DK

丹麦语(丹麦)    da_DK

英语(以色列)    en_IL

希伯来语(以色列)    he_IL

英语(南非)    en_ZA

英语(印度)    en_IN

英语(挪威)    en_NO

英语(新加坡)    en_SG

英语(新西兰)    en_NZ

英语(印度尼西亚)    en_ID

英语(菲律宾)    en_PH

英语(泰国)    en_TH

英语(马来西亚)    en_MY

英语(阿拉伯)    en_XA

韩文(韩国)    ko_KR

日语(日本)    ja_JP

荷兰语(荷兰)    nl_NL

荷兰语(比利时)    nl_BE

葡萄牙语(葡萄牙)    pt_PT

葡萄牙语(巴西)    pt_BR

法语(法国)    fr_FR

法语(卢森堡)    fr_LU

法语(瑞士)    fr_CH

法语(比利时)    fr_BE

法语(加拿大)    fr_CA

西班牙语(拉丁美洲)    es_LA

西班牙语(西班牙)    es_ES

西班牙语(阿根廷)    es_AR

西班牙语(美国)    es_US

西班牙语(墨西哥)    es_MX

西班牙语(哥伦比亚)    es_CO

西班牙语(波多黎各)    es_PR

德语(德国)    de_DE

德语(奥地利)    de_AT

德语(瑞士)    de_CH

俄语(俄罗斯)    ru_RU

意大利语(意大利)    it_IT

希腊语(希腊)    el_GR

挪威语(挪威)    no_NO

匈牙利语(匈牙利)    hu_HU

土耳其语(土耳其)    tr_TR

捷克语(捷克共和国)    cs_CZ

斯洛文尼亚语    sl_SL

波兰语(波兰)    pl_PL

瑞典语(瑞典)    sv_SE

西班牙语(智利)    es_CL

 

参考文章:https://blog.csdn.net/u012702547/article/details/104667731


相关文章
|
1月前
|
前端开发 Java Spring
SpringBoot项目thymeleaf页面支持词条国际化切换
SpringBoot项目thymeleaf页面支持词条国际化切换
68 2
|
6月前
|
Java 数据安全/隐私保护 网络架构
一个简单的示例在spring boot中实现国际化
一个简单的示例在spring boot中实现国际化
|
4月前
|
Java Spring 自然语言处理
Spring 框架里竟藏着神秘魔法?国际化与本地化的奇妙之旅等你来揭开谜底!
【8月更文挑战第31天】在软件开发中,国际化(I18N)与本地化(L10N)对于满足不同地区用户需求至关重要。Spring框架提供了强大支持,利用资源文件和`MessageSource`实现多语言文本管理。通过配置日期格式和货币符号,进一步完善本地化功能。合理应用这些特性,可显著提升应用的多地区适应性和用户体验。
45 0
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的北工国际健身俱乐部的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的北工国际健身俱乐部的详细设计和实现(源码+lw+部署文档+讲解等)
|
5月前
|
存储 Java UED
Spring Boot中的国际化处理
Spring Boot中的国际化处理
|
5月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的北工国际健身俱乐部附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的北工国际健身俱乐部附带文章源码部署视频讲解等
26 0
|
6月前
|
自然语言处理 Java UED
Spring Boot中的国际化配置
Spring Boot中的国际化配置
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的北工国际健身俱乐部的详细设计和实现
基于SpringBoot+Vue的北工国际健身俱乐部的详细设计和实现
27 0
|
7月前
|
存储 人工智能 运维
spring国际化 - i18n
spring国际化 - i18n
106 0
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
223 2