Springboot与国际化(i18n)

一、什么是国际化?

  • 国际化就是在不修改内部代码的情况下,根据不同语言及地区显示相应的语言界面。

  • i18n的由来→internationalization,数一下,首字母i和末位字母之间有18个字母。类似的命名还有很多,例如k8s。

  • Springboot已经对i18n国际化做了自动配置,自动配置类。

org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration

如果想自定义国际化,通过@Autowired配置使用MessageSource进行自定义。

二、前端联合后端实现国际化。

一图解释什么是国际化:

在这里插入图片描述

原理:由前端页面某个元素(中文/English)返回给后端一个标识,后端根据标识获取地域信息,Springboot框架内置的MessageSource会获取该标识(图中只有两种标识,因此只有两种语种)来进行语种转换。当然转换的前提是要提前通过messages.properties文件来配置相应语言。

  • 前端代码如下:(l='zh_CN’和l='en_US’就是标识)

  •   <!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 href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.2.1/css/bootstrap.css}" rel="stylesheet">
      		<!-- Custom styles for this template -->
      		<link href="asserts/css/signin.css" rel="stylesheet">
      	</head>
      
      	<body class="text-center">
      		<form class="form-signin" action="dashboard.html">
      			<img class="mb-4" src="asserts/img/bootstrap-solid.svg" alt="" width="72" height="72">
      			<h1 class="h3 mb-3 font-weight-normal" th:text="#{login.btn}">Please sign in</h1>
      			<label class="sr-only">Username</label>
      			<input type="text" class="form-control" th:placeholder="#{login.username}" placeholder="Username" required="" autofocus="">
      			<label class="sr-only">Password</label>
      			<input type="password" class="form-control" th:placeholder="#{login.password}" placeholder="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" th:text="#{login.sign}" type="submit">Sign in</button>
      			<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
      			<a class="btn btn-sm" th:href="@{/login.html(l='zh_CN')}">中文</a>
      			<a class="btn btn-sm" th:href="@{/login.html(l='en_US')}">English</a>
      		</form>
      	</body>
      </html>
    
  • 后端代码:

  •   package com.example.bootstudy.component;
      
      import org.springframework.util.StringUtils;
      import org.springframework.web.servlet.LocaleResolver;
      
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.util.Locale;
      
      /**
       * ----------------------------------------------------------------
       * @description:   自定义Local地域的解析
       * @author: Create by Liu Wen at 2020-07-08 17:34
       * ----------------------------------------------------------------
       **/
      public class MyLocaleResolver implements LocaleResolver {
      
          @Override
          public Locale resolveLocale(HttpServletRequest httpServletRequest) {
              String l = httpServletRequest.getParameter("l");
              Locale locale = Locale.getDefault();
              if(!StringUtils.isEmpty(l)){
                  String[] atts = l.split("_");
                  locale = new Locale(atts[0],atts[1]);
              }
              return locale;
          }
      
          @Override
          public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
      
          }
      }
    
    package com.example.bootstudy.config;
    
    import com.example.bootstudy.component.MyLocaleResolver;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.LocaleResolver;
    import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    /**
     * ----------------------------------------------------------------
     * @description:   将自定义的MyLocaleResolver配置到Springboot框架中
     * @author: Create by Liu Wen at 2020-07-08 17:34
     * ----------------------------------------------------------------
     **/
    @Configuration
    public class MymvcConfig implements WebMvcConfigurer {
        @Override
        public void addViewControllers(ViewControllerRegistry registry) {
            registry.addViewController("/").setViewName("login");
            registry.addViewController("/login.html").setViewName("login");
        }
    
        @Bean
        public LocaleResolver localeResolver(){
            return new MyLocaleResolver();
        }
    }
    
  • login.properties文件配置

  •   #login_en_US.properties文件
          
      login.btn=\u8BF7\u767B\u5F55
      login.password=\u5BC6\u7801
      login.remember=\u8BB0\u4F4F\u6211
      login.sign=\u767B\u5F55
      login.username=\u7528\u6237\u540D
          
      #login_zh_CN.properties文件
      login.btn=Please sign in
      login.password=Password
      login.remember=Remember me
      login.sign=Sign in
      login.username=Username
    
  • application.yml配置

  •   spring:
        messages:
          basename: i18n/login
    

代码结构如图:

在这里插入图片描述

三、服务端国际化(Springboot内置国际化)

服务端的国际化一般用于信息提示。不集成前端。

可以直接使用默认的Springboot内置国际化,也可以自定义。代码如下:

  • messages.properties文件配置

  •   #messages_zh_CN.properties文件
      MSGFM00100001=\u8282\u70B9(id:{0})\u4E0D\u5B58\u5728.
      MSGFM00100002=\u8282\u70B9(id:{0})\u4E0D\u662F\u6D41\u7A0B\uFF0C\u6240\u4EE5\u5E76\u6CA1\u6709\u6D41\u7A0B\u56FE.
      MSGFM00100003=\u9879\u76EE(id:{0})\u5DF2\u7ECF\u5B58\u5728\u8BE5\u8282\u70B9.
      MSGFM00100004=\u9879\u76EE(id:{0})\u7684\u6839\u8282\u70B9\u4E0D\u5B58\u5728.
      MSGFM00100005=\u8282\u70B9(id:{0})\u7684\u7236\u8282\u70B9\u4E0D\u5B58\u5728.
      
      #messages_en_US.properties文件
      MSGFM00100001=The node(id:{0}) does not exist.
      MSGFM00100002=The node(id:{0}) is not a "FLOW" node, so it can not have a graph.
      MSGFM00100003=The project(id:{0}) has already got a root node.
      MSGFM00100004=The root node of project(id:{0}) does not exist.
      MSGFM00100005=The parent node(id:{0}) does not exist.
    
  • 自定义MessageSource工具:

  •   package com.sample.utils;
      
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.context.MessageSource;
      import org.springframework.context.i18n.LocaleContextHolder;
      import org.springframework.stereotype.Component;
      
      import java.util.Locale;
      
      /**
       * MessageSource工具
       * 依賴{@link MessageSource}
       *
       * @author Catscan
       * @date 2019-06-07
       */
      @Component
      public class MessageSourceUtil {
      
          @Autowired
          private MessageSource messageSource;
      
          public String getMessage(String code) {
              return getMessage(code, null);
          }
      
          public String getMessage(String code, Object[] args) {
              return getMessage(code, args, "");
          }
      
          public String getMessage(String code, Object[] args, String defaultMsg) {
              // 這裡可以使用一些比較trick的方法動態設定語言
              // 可以做全站全局、單個request,當然,方法需要根據不同情況修改
              Locale locale = LocaleContextHolder.getLocale();
              return messageSource.getMessage(code, args, defaultMsg, locale);
          }
      }
    
  • 测试内置的国际化与自定义的国际化

  •   package com.sample.controller;
      
      import com.sample.utils.MessageSourceUtil;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.context.MessageSource;
      import org.springframework.http.ResponseEntity;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      import java.util.HashMap;
      import java.util.Locale;
      import java.util.Map;
      
      /**
       * 測試用的Controller
       *
       * @author Catscan
       * @date 2019-06-07
       */
      @RestController
      @RequestMapping("/")
      public class MessageController {
          @Autowired
          private MessageSourceUtil messageSourceUtil;
      
          @Autowired
          private MessageSource messageSource;
      
          /**
           * 測試使用{@link MessageSource}
           *
           * @return {@link ResponseEntity}
           */
          @RequestMapping("/message")
          public ResponseEntity pingResource(){
              Map<String ,String> result = new HashMap<>(3);
      
              result.put("default",messageSource.getMessage("hello", null, "", null));
              result.put("en_US",messageSource.getMessage("hello", null, "", Locale.US));
              result.put("zh_CN",messageSource.getMessage("hello", null, "", Locale.SIMPLIFIED_CHINESE));
      
              return ResponseEntity.ok(result);
          }
      
      
          /**
           * 測試使用{@link MessageSourceUtil}
           *
           * @return {@link ResponseEntity}
           */
          @RequestMapping("/util")
          public ResponseEntity pingUtil(){
              return ResponseEntity.ok(messageSourceUtil.getMessage("hello"));
          }
      }
    

    多语言环境是定义在java.util.Locale类中的,如:

    ...
    static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
    static public final Locale CHINA = SIMPLIFIED_CHINESE;
    static public final Locale UK = createConstant("en", "GB");
    static public final Locale US = createConstant("en", "US");
    static public final Locale CANADA = createConstant("en", "CA");
    ...
    

    分析:在MessageSource.getMessage(...)所有方法中,都有Locale参数,指定区域信息。
    当调用时,要如果指定位置为:Locale.CHINA,这时ResourceBundelMessageSource会从messages_zh_CN.properties中寻找对应的键值。
    当给出Locale参数值为null,空的区域信息;或者对应的properties文件中没有找到对应的键值对,那么ResourceBundelMessageSource默认会从messages.properties中寻找键,当都找不到的时候,会返回空字符串。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Spring Boot 国际化i18n)是指在应用程序中支持多种语言和文化的能力。通过使用 Spring Boot 的 i18n 功能,可以轻松地将应用程序本地化为不同的语言和文化,以便更好地满足不同用户的需求。在 Spring Boot 中,可以使用 MessageSource 接口和 ResourceBundle 类来实现国际化。通过在应用程序中使用这些类,可以轻松地将应用程序的文本和消息本地化为不同的语言和文化。 ### 回答2: Spring Boot 是一种基于 Spring 框架的快速应用程序开发工具,可以快速创建基本的 Spring 应用程序并自动引入所需的依赖项。在 Spring Boot 应用程序中,国际化i18n)是非常重要的功能之一,因为它可以帮助应用程序更好地支持不同国家和地区的用户。 国际化是指将应用程序的用户界面以及其他文字内容翻译成不同语言,以便支持不同地区的用户。在 Spring Boot 中,国际化可以通过使用 Spring 的 MessageSource 接口来实现。MessageSource 是一个用于加载和解析国际化资源文件的接口,并用于将这些资源文件中的消息文本转换成应用程序可以使用的文本。国际化资源文件通常以属性文件的形式存在,其中包含被翻译的消息文本。 在 Spring Boot 中,可以使用 @EnableAutoConfiguration 注解自动配置 MessageSource,并且Spring Boot 的默认消息源加载器将查找以下资源文件:messages.properties、messages_en.properties、messages_zh.properties等。这些文件必须在 classpath 路径下的某个位置可以找到。 在应用程序中使用国际化消息时,需要在 bean 中注入 MessageSource,并使用它来读取需要翻译的消息文本。例如,可以使用以下代码获取“hello”的国际化文本: @Autowired private MessageSource messageSource; String helloText = messageSource.getMessage("hello", null, LocaleContextHolder.getLocale()); 这个代码片段将使用 MessageSource 来查找可以匹配“hello”关键字的消息文本,并返回一个形如“你好”的字符串。LocaleContextHolder.getLocale() 方法将返回当前用户的语言环境,以便实现语言的不同切换。 总之,Spring Boot 的国际化(i18n)功能非常强大,并且很容易实现。通过使用 MessageSource 接口和属性文件,应用程序可以支持多种语言环境,为不同国家和地区的用户提供更好的体验。 ### 回答3: Spring Boot 是一款使用 Spring 框架的 Java 开发框架,它在优化 Spring 框架的同时,也非常注重国际化支持。在 Spring Boot 中,国际化i18n)是一项非常重要的功能,它允许开发人员在应用程序中使用多种语言,以满足不同地区用户的需求。 在 Spring Boot 中实现国际化功能,可以通过配置文件(Properties)或 Yaml 文件来完成。在配置文件中,可以定义键值对的形式来保存不同语言版本的文本信息,如下所示: ```properties hello.world = Hello World! ``` 在应用程序中,可以通过 Spring Boot 的 MessageSource 解析器来获取配置文件中的文本信息,如下所示: ```java @Autowired private MessageSource messageSource; public String getHelloWorldMessage(){ return messageSource.getMessage("hello.world", null, Locale.getDefault()); } ``` 在上面的代码中,messageSource.getMessage 方法中的三个参数分别代表需要获取的文本信息的键、参数和语言环境。Locale.getDefault() 方法会根据当前用户的语言环境自动选择合适的语言版本。 除了使用配置文件之外,还可以使用数据库或注解来进行国际化。Spring Boot 支持使用 Thymeleaf 模板引擎进行注解国际化。可以在模板中使用 @{...} 语法将文本信息注入到 HTML 标签中,如下所示: ```html <h1 th:text="#{welcome.message}">Welcome to our site!</h1> ``` 在上面的代码中,#{welcome.message} 表示要注入的文本信息的键。 总之,Spring Boot 的国际化支持非常丰富,开发人员可以根据具体需求选择不同的方式来实现国际化功能。这将大大提升应用程序的跨地区使用能力,也为开发人员提供了更加便捷和灵活的开发体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的程序猿~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值