SpringBoot3项目实现国际化的示例详解

 更新时间:2025年08月13日 09:08:28   作者:xiguolangzi  
这篇文章主要为大家详细介绍了SpringBoot3如何在项目中实现国际化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

下面小编就来和大家简单介绍一下springBoot3 项目实现国际化的完整代码吧

1 创建国际化资源文件

  //src/main/resources/i18n/Resource Bundle 'messages'
      messages.properties (默认)
      messages_en_US.properties (英文)
      messages_zh_CN.properties (中文)
    
  // 翻译文件内容:
        # {}是参数引用,用于拼接传参
        user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟

2 配置 application.yml

  # Spring配置
  spring:
    # 资源信息
    messages:
      # 国际化资源文件路径,如果有多个通过逗号隔开,这里的messages不是路径,而是文件名前缀
      basename: i18n/messages
      encoding: UTF-8

3 维护 i8n 配置类

  package com.okyun.framework.config;
  ​
  /**
   * 资源文件配置加载
   * 语言切换优先级 -> 1 请求lang参数语言 -> 2 浏览器设置的默认语言 -> 3 该系统默认语言(简体中文)
   *
   * @author hubiao
   */
  @Configuration
  public class I18nConfig implements WebMvcConfigurer
  {
      /**
       * 语言切换
       * @return
       */
      @Bean
      public LocaleResolver localeResolver()
      {
          // SessionLocaleResolver 用来解析和存储用户的 Locale 信息在会话 (session) 中
          SessionLocaleResolver slr = new SessionLocaleResolver();
          // 设置默认语言 = 简体中文,可以用 Locale.CHINA
          slr.setDefaultLocale(Constants.DEFAULT_LOCALE);
          return slr;
      }
  ​
      /**
       * LocaleChangeInterceptor: Spring 提供的用于切换 Locale 的拦截器,拦截 HTTP 请求中的参数来确定用户想要切换到的语言
       * lci.setParamName("lang"): 设置 URL 请求中的参数名为 lang
       * 即用户可以通过传递 ?lang=xx 来切换语言(如 ?lang=zh_CN 切换到简体中文,?lang=en 切换到英文)
       * @return
       */
      @Bean
      public LocaleChangeInterceptor localeChangeInterceptor()
      {
          LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
          // 参数名
          lci.setParamName("lang");
          return lci;
      }
  ​
      /**
       * WebMvcConfigurer 添加自定义拦截器
       * @param registry
       */
      @Override
      public void addInterceptors(InterceptorRegistry registry)
      {
          // 添加拦截器
          registry.addInterceptor(localeChangeInterceptor());
      }
  }

4 封装消息工具

  package com.okyun.common.utils;
  ​
  import org.springframework.context.MessageSource;
  import org.springframework.context.i18n.LocaleContextHolder;
  import com.okyun.common.utils.spring.SpringUtils;
  ​
  /**
   * 获取i18n资源文件
   * 
   * @author hubiao
   */
  public class MessageUtils
  {
      /**
       * 根据消息键和参数 获取消息 委托给spring messageSource
       *
       * @param code 消息键
       * @param args 参数
       * @return 获取国际化翻译值
       */
      public static String message(String code, Object... args)
      {
          // MessageSource:Spring 的国际化资源接口,主要用于获取不同语言环境下的消息内容
          MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
          // LocaleContextHolder.getLocale():从 LocaleContextHolder 中获取当前线程的 Locale(语言环境)
          return messageSource.getMessage(code, args, LocaleContextHolder.getLocale());
      }
  }

5 后台业务中使用

  AjaxResult.error(MessageUtils.message("user.password.retry.limit.exceed",new Object[] { retryLimitCount, lockTime }))

6 前端切换语言

 /**
  * 切换语言
  * @param lang
  * @return
  */
  @GetMapping("/changeLanguage")
  public AjaxResult changeLanguage(String lang)
  {
    return AjaxResult.success();
  }

7 特殊国际化处理 - 参数校验注解

/**
* 参数验证国际化
*/
@Size(max = 30, message = "编码最大长度30个字符")
@Pattern(regexp = "^[^+-].*", message = "编码不能以 + 或 - 开头")
private String productNo;

// 举例 @Size(max = 30, message = "size.max.valid")
# Spring 会自动从 `messages.properties` 加载对应的消息
size.between.valid=长度必须在{min}到{max}个字符之间
size.max.valid=长度不能超过{max}个字符
size.min.valid=长度不能少于{min}个字符

8 特殊国际化处理 - Excel列名

8.1 Excel注解添加i18n字段

package com.okyun.common.annotation;

/**
 * 自定义导出Excel数据注解
 * 
 * @author hubiao
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Excel{
...

/**
 * 国际化Key(优先级高于name).
 * 示例: excel.user.name
 */
public String i18nKey() default "";

...

}

8.2 ExcelUtil 方法添加获取国际化逻辑

package com.okyun.common.utils.poi;


/**
 * Excel相关处理
 * @author hubiao
 */
public class ExcelUtil<T>{

    ...
    // 国际化 - 注入MessageSource(若依中可通过SpringUtils获取)
    private static final MessageSource messageSource = SpringUtils.getBean(MessageSource.class);


    /**
     * 获取国际化表头名称
     */
    private String getI18nHeader(Excel excelAttr) {
        if (StringUtils.isNotEmpty(excelAttr.i18nKey())) {
            return messageSource.getMessage(
                    excelAttr.i18nKey(),
                    null,
                    LocaleContextHolder.getLocale()
            );
        }
        return excelAttr.name(); // 默认返回name
    }

    /**
     * 创建单元格
     */
    public Cell createHeadCell(Excel attr, Row row, int column){

        ...

        // 写入列信息 - 国际化
        cell.setCellValue(getI18nHeader(attr));

        ...

    }



    /**
     * 添加单元格
     */
    public Cell addCell(Excel attr, Row row, T vo, Field field, int column){

        ......

        else if (StringUtils.isNotEmpty(dictType) && StringUtils.isNotNull(value)) {
            String label = DictUtils.getDictLabel(
                    dictType,
                    Convert.toStr(value),
                    separator,
                    LocaleContextHolder.getLocale() // 传递当前语言环境
            );
            cell.setCellValue(label);
        }

        ......

    }

    ...

}

8.3 字典数据国际化

package com.okyun.common.utils;


/**
 * 字典工具类
 * 
 * @author hubiao
 */
public class DictUtils{

    ......

    /**
     * 获取国际化字典标签(完整实现)
     * @param dictType 字典类型
     * @param dictValue 字典值
     * @param separator 分隔符
     * @param locale 语言环境
     * @return 字典标签
     */
    public static String getDictLabel(String dictType, String dictValue, String separator, Locale locale) {
        // 1. 尝试获取国际化标签
        String i18nKey = "dict." + dictType + "." + dictValue;
        MessageSource messageSource = SpringUtils.getBean(MessageSource.class);
        String i18nLabel = messageSource.getMessage(i18nKey, null, null, locale);

        // 2. 如果不存在国际化配置,回退到系统字典
        if (i18nLabel == null || i18nKey.equals(i18nLabel)) {
            return getDictLabel(dictType, dictValue, separator); // 调用原有方法
        }
        return i18nLabel;
    }

    ......

}

8.4 项目实战中使用

8.4.1 @Excel注解

/** 
* 商品状态 
* dictType 字典类型
* i18nKey 映射的字段名
*/
@Excel(name = "商品状态", dictType = "product_status", i18nKey = "product.product.status")
private Integer productStatus;

/** 
* 编码
* i18nKey 映射的字段名
*/
@Excel(name = "编码", i18nKey = "product.product.code")
private String productNo;

8.4.2 维护映射文件

# excel导出/导入 - 字段名映射
product.product.code=商品编码
product.product.status=商品状态

# dictData 的 value 对应 label
# dict 固定前缀
# dictType 字典类型
# 0 字典值
# 启售 字典label
dict.product_status.0=启售
dict.product_status.1=停售

到此这篇关于SpringBoot3项目实现国际化的示例详解的文章就介绍到这了,更多相关SpringBoot3国际化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中实现Comparable接口实现自定义排序的示例

    java中实现Comparable接口实现自定义排序的示例

    下面小编就为大家带来一篇java中实现Comparable接口实现自定义排序的示例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • Java CRM系统用户登录功能实现代码实例

    Java CRM系统用户登录功能实现代码实例

    这篇文章主要介绍了Java CRM系统用户登录功能实现代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Springboot如何使用Aspectj实现AOP面向切面编程

    Springboot如何使用Aspectj实现AOP面向切面编程

    这篇文章主要介绍了Springboot如何使用Aspectj实现AOP面向切面编程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Java实现简单班级管理系统

    Java实现简单班级管理系统

    这篇文章主要为大家详细介绍了Java实现简单班级管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Java实现在线五子棋对战游戏(人机对战)

    Java实现在线五子棋对战游戏(人机对战)

    这篇文章主要为大家详细介绍了如何利用Java语言实现在线五子棋对战游戏(人机对战),文中的实现步骤讲解详细,感兴趣的可以尝试一下
    2022-09-09
  • java集合类HashMap源码解析

    java集合类HashMap源码解析

    这篇文章主要介绍了Java集合之HashMap用法,结合实例形式分析了java map集合中HashMap定义、遍历等相关操作技巧,需要的朋友可以参考下
    2021-06-06
  • Hadoop使用hdfs指令查看hdfs目录的根目录显示被拒的原因及解决方案

    Hadoop使用hdfs指令查看hdfs目录的根目录显示被拒的原因及解决方案

    这篇文章主要介绍了Hadoop使用hdfs指令查看hdfs目录的根目录显示被拒的原因及解决方案,分布式部署hadoop,服务机只有namenode节点,主机包含其他所有节点,本文给大家介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • Java线程状态变换过程代码解析

    Java线程状态变换过程代码解析

    这篇文章主要介绍了Java线程状态变换过程代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • 浅析mybatis和spring整合的实现过程

    浅析mybatis和spring整合的实现过程

    据官方的说法,在Mybatis3问世之前,Spring3的开发工作就已经完成了,所以Spring3中还是没有对Mybatis3的支持。因此由Mybatis社区自己开发了一个Mybatis-Spring用来满足Mybatis用户整合Spring的需求,下面通过Mybatis-Spring来整合Mybatis跟Spring的用法做介绍
    2015-10-10
  • Java中String.split()的最详细源码解读及注意事项

    Java中String.split()的最详细源码解读及注意事项

    以前经常使用String.split()方法,但是从来没有注意,下面这篇文章主要给大家介绍了关于Java中String.split()最详细源码解读及注意事项的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-07-07

最新评论