Spring Cloud微服务下如何配置I8n

spring,cloud,i8n · 浏览次数 : 17

小编点评

I18n国际化(I18n)是指设计和开发产品的过程,使产品能够适应多种语言和文化环境,而无需进行大量代码更改。它通常包括创建一个基础版本的产品,然后通过配置和资源文件为不同语言和文化环境添加支持。这样,当产品需要在新的地理区域或语言环境中使用时,只需添加或更新相应的资源文件,而无需修改产品本身的代码。 在Java后端中,Spring Boot提供了对I18n的支持。要添加国际化资源文件,可以在`src/main/resources`目录下创建相应的语言文件夹(如`messages`),并在其中创建国际化资源文件。例如,为了添加中文和英文两种语言的资源文件,可以创建名为`messages_zh_CN.properties`和`messages_en_US.properties`的文件。 要在Spring Boot项目中配置I18n,可以使用`@Value`注解将国际化资源文件注入到Java类中,或者使用`MessageSource`接口从Spring Boot中获取请求上下文的语言并加载相应的资源文件。此外,还可以在Spring Cloud项目中自定义一个`MessageSource`,以便从公共项目中读取I18n配置。 总之,I18n国际化是一种让产品适应多种语言和文化环境的方法,它通过添加资源文件和配置来实现,从而简化了多语言支持的开发过程。

正文

什么是I8n

国际化(I18n)指的是设计和开发产品的过程,使得它们能够适应多种语言和文化环境,而不需要进行大量的代码更改。这通常涉及到创建一个基础版本的产品,然后通过配置和资源文件来添加对不同语言和地区的支持。

这样,当产品需要在新的地理区域或语言环境中使用时,只需要添加或更新相应的资源文件,而不需要修改产品本身的代码。

"I18n" 是 "Internationalization" 的缩写形式,之所以是 "I18n" 而不是 "Int" 或者其他缩写,是因为 "Internationalization" 这个词的第一个字母是 "I",最后一个字母是 "n",而在这两个字母之间有 18 个字符。因此,"I18n" 成为了一个流行的缩写方式,类似的还有 "K8s" 。

Spring Boot I18n

I8n体现在Java后端比较常见的就是错误提示,而SpringBoot本身就提供了对I8n的支持。使用也非常简单,可以参考一下官方文档

添加国际化资源文件

SpringBoot默认会读取classpath/resource下的messages目录里的国际化资源文件,可以通过下面这个配置更改:

spring.messages.basename=messages

咱们先通过Idea 创建国际化资源文件,方法如下:

Untitled
Untitled

创建完成后在reources目录下能看到这些国际化资源文件,图中为了演示,定义了咱们开发中比较常见的登录错误提示信息。

Untitled

创建工具类

创建工具类的目的是方便咱们获取国际化信息

public class I18nUtil {
 public static String getI18nMessage(String code) {
         try {
           // SpringBoot提供有一个MessageSource的默认实现
             MessageSource messageSource = SpringUtils.getBean("messageSource");
             // 从SpringBoot中获取请求上下文 语言
             Locale locale = LocaleContextHolder.getLocale();
             // 因为我项目只有中文和英文,所以判断一下除了指定中文,否则默认使用英文  
             // 这里对简体中文的定义,Locale[] SIMPLIFIED_CHINESE = {Locale.CHINESE, Locale.CHINA, Locale.SIMPLIFIED_CHINESE, Locale.PRC};
             if (Arrays.stream(LocaleUtils.SIMPLIFIED_CHINESE).toList().contains(locale)) {
                 locale = Locale.SIMPLIFIED_CHINESE;
             } else {
                locale = Locale.US;
             }
            return messageSource.getMessage(code, null, locale);
         } catch (Exception e) {
             log.error("获取国际化内容异常", e);
             // 如果获取国际化信息失败就返回原内容
             return code;
         }
     }
}

定义接口统一返回类

@Data
public class RestResult<Timplements Serializable {

    private static final long serialVersionUID = 1L;

    /** 状态标识码 */
    private String code;

    /** 描述信息 */
    private String message;

    /** 数据 */
    private T data;
    
    public String getMessage(){
     if (StrUtil.isNotEmpty(this.code)) {
       // 获取I8n
      return I18nUtil.getI18nMessage(this.code)
     }
     return this.message;
    }
    
    // 省略其他方法。。。
}

请求头添加语言编码

curl -H "Accept-Language: zh-CN" http://example.com

Spring Cloud 配置I8n

上面是一个简单的是SpringBoot项目配置I8n的流程,但是在Spring Cloud下通常会有多个服务(SpringBoot项目)。按照我们的习惯一般有一个公共项目(common),用于封装POJO 和一些通用的工具类、常量类之类的功能,然后把这个项目打成jar包,其他业务服务都会依赖这个项目,达到功能复用的目的。通用我们也会将一些通用的错误信息(比如:用户Id不能为空)放到common项目里面,那么怎么把这些通用错误信息配置成I8n呢?

按照上面所说,我们把common项目打成jar包供其他业务服务使用,那么当其他服务引入common依赖以后,common就和业务服务同处于一个Spring容器,这时候上面的I8n配置就无法读取到common里面的I8n配置了(上面讲过了SpringBoot默认读取的是项目classpath/resource下的配置文件)。因此我们需要自定义一个MessageSource 然后读取common下的I8n配置就可以了。

  1. 首先,我们在commonresource下创建I8n配置文件,方法和上面一样,因为和业务服务同处一个Spring容器,所以我们需要将资源名称区分开,我们暂且就叫common_messages, 如下图所示:
Untitled
Untitled
  1. 然后,我们配置一个自定义MessageSource Bean,并且读取我们设置的common_messages
@Bean(name = "commonMessageSource")
public ResourceBundleMessageSource resourceBundleMessageSource() throws IOException {
    ResourceBundleMessageSource source = new ResourceBundleMessageSource();
    source.setDefaultEncoding(StandardCharsets.UTF_8.displayName());
    source.setBasename("common_messages");
    return source;
}
  1. 最后,调整I8nUtil逻辑,先读取业务服务自己的I8n,如果没有再从common I8n获取,如果还没有则返回原code
public class I18nUtil {
 public static String getI18nMessage(String code) {
         try {
           // SpringBoot提供有一个MessageSource的默认实现
             MessageSource messageSource = SpringUtils.getBean("messageSource");
             // 从SpringBoot中获取请求上下文 语言
             Locale locale = LocaleContextHolder.getLocale();
             // 因为我项目只有中文和英文,所以判断一下除了指定中文,否则默认使用英文  
             // 这里对简体中文的定义,Locale[] SIMPLIFIED_CHINESE = {Locale.CHINESE, Locale.CHINA, Locale.SIMPLIFIED_CHINESE, Locale.PRC};
             if (Arrays.stream(LocaleUtils.SIMPLIFIED_CHINESE).toList().contains(locale)) {
                 locale = Locale.SIMPLIFIED_CHINESE;
             } else {
                locale = Locale.US;
             }
            try{
              // 先读取业务服务自己配置的I8n
             return messageSource.getMessage(code, null, locale);
            }catch (NoSuchMessageException e) {
                // 如果没有获取到,再从common里面读取I18n
              ResourceBundleMessageSource commonMessageSource = SpringUtils.getBean("commonMessageSource");
                return commonMessageSource.getMessage(code, null, locale);
            }
         } catch (Exception e) {
             log.error("获取国际化内容异常", e);
             // 如果获取国际化信息失败就返回原内容
             return code;
         }
     }
}

本文使用 markdown.com.cn 排版

与Spring Cloud微服务下如何配置I8n相似的内容:

Spring Cloud微服务下如何配置I8n

什么是I8n 国际化(I18n)指的是设计和开发产品的过程,使得它们能够适应多种语言和文化环境,而不需要进行大量的代码更改。这通常涉及到创建一个基础版本的产品,然后通过配置和资源文件来添加对不同语言和地区的支持。 这样,当产品需要在新的地理区域或语言环境中使用时,只需要添加或更新相应的资源文件,而不

SpringCloud-Config配置中心搭建保姆级教程

一、分布式配置中⼼ 在使⽤微服务架构开发的项⽬中,每个服务都有⾃⼰的配置⽂件(application.yml),如果将每个服务的配置⽂件直接写在对应的服务中,存在以下问题: 1. 服务开发完成之后,需要打包部署,配置⽂件也会打包在jar⽂件中,不便于项⽬部署之后的配置修改(在源码中修改——重新打包—

[转帖]k8s发布Spring cloud+eureka架构服务优雅启动停止方案

本文转载自昆仑枫的简书https://www.jianshu.com/p/6d393cbb694a Spring cloud+eureka是目前微服务主流解决方案之一,kubernetes则是广泛应用的发布工具,两者结合使用很常见。而两者结合时如何优雅启停从而实现无感发布很关键。下面将从不做特殊处理

0停机迁移Nacos?Java字节码技术来帮忙

摘要:本文介绍如何将Spring Cloud应用从开源Consul无缝迁移至华为云Nacos。 本文分享自华为云社区《0停机迁移Nacos?Java字节码技术来帮忙》,作者:华为云PaaS服务小智。 1.市场迁移云环境痛点 市场微服务迁移云环境难主要有以下几点场景: • 微服务规模小,使用微服务引擎

微服务使用openfeign调用单点的会话失效问题

# 项目Springcloud,认证中心方式实现SSO使用开源框架Sa-Token >本身的单独访问每个客户端服务的单点就没有问题。然后单点通过Fegin调用就不好使了! ##### 主要使用的Sa-Token的微服务单点功能 ##### 使用的依赖如下 ```xml cn.dev33 sa-tok

SpringCloud-ZipKin搭建保姆级教程

服务链路追踪 一、服务追踪说明 微服务架构是通过业务来划分服务的,使⽤REST调⽤。对外暴露的⼀个接⼝,可能需要 很多个服务协同才能完成这个接⼝功能,如果链路上任何⼀个服务出现问题或者⽹络超 时,都会形成导致接⼝调⽤失败。 随着业务的不断扩张,服务之间互相调⽤会越来越复杂,它们之间的调⽤关系也许如下

Ribbon默认负载均衡规则替换为NacosRule

> 近期博主在参与一个 Spring Cloud 搭建,版本为 Hoxton.SR12,服务注册发现组件为 Nacos 的老项目时,发现项目负载均衡组件 Ribbon 的负载均衡规则在某些场景下不够完美,比如新版本上线,需要重启服务。因此写了这边文章与大家分享。 在微服务架构中,负载均衡是实现高可用

Nacos集群启动注意事项

简介 Nacos是阿里巴巴开源的一套服务注册发现的应用 使用简单灵活, 是spring Cloud Alibaba的组成部分 现在拆分微服务的部署情况下,极大的需求nacos服务作为支撑 单点情况下存在宕机的危险, 所以最近为了进行测试验证. 所以准备启用一套集群版本的nacos集群进行测试兼容性验

Spring Cloud微服务核心架构分析

Spring Cloud是一个相对比较成熟的微服务框架。虽然,Spring Cloud于2016年才推出1.0的release版本, 时间最短, 但是相比Dubbo等RPC框架, Spring Cloud提供的全套的分布式系统解决方案。 Spring Cloud是一系列框架的有序集合。它利用Spri

基于 Spring Cloud 的微服务脚手架

基于 Spring Cloud 的微服务脚手架 作者: Grey 原文地址: 博客园:基于 Spring Cloud 的微服务脚手架 CSDN:基于 Spring Cloud 的微服务脚手架 本文主要介绍了基于 Spring Cloud Finchley 和 Spring Boot 2.0.x 版本