跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

SpringBoot 国际化 i18n 实战:配置文件与动态切换方案

介绍 SpringBoot 国际化(i18n)的实现方案。涵盖核心概念如 MessageSource、LocaleResolver。详细讲解基于配置文件的静态实现流程,包括多语言文件命名规则、application.yml 配置及中文乱码处理。同时提供自定义语言解析器与拦截器的代码示例,支持通过请求头或 Session 切换语言。最后封装了国际化工具类简化业务调用,并展示了控制器中的使用方式。

无尘发布于 2026/3/24更新于 2026/8/1720K 浏览

前言

在全球化业务场景下,系统适配多语言已成为标配需求。SpringBoot 作为主流的 Java 开发框架,提供了完善的国际化(i18n)解决方案。本文将从实战角度出发,完整讲解两种企业级 i18n 实现方案:基于配置文件的静态实现(适配简体中文、繁体中文、英文)和基于数据库的动态实现(支持运行时修改语言配置),同时覆盖校验注解国际化、性能优化、常见问题排查等核心要点。

一、国际化基础认知

1.1 核心概念

i18n 的核心目标是让系统在不修改代码的前提下,通过配置适配不同语言和地区的使用习惯。SpringBoot 中实现 i18n 的核心依赖是:

  • MessageSource:消息源接口,负责加载和解析多语言消息,默认实现为 ResourceBundleMessageSource(基于配置文件)。
  • Accept-Language:语言地区标识,格式为 语言代码_国家/地区代码,如:
    • 简体中文:zh_CN
    • 繁体中文:zh_TW
    • 英文(美国):en_US
  • LocaleResolver:语言解析器,负责从请求中获取/设置当前 Locale。
  • LocaleChangeInterceptor:语言切换拦截器,用于拦截请求参数实现语言动态切换。

1.2 核心原理

SpringBoot 启动时,MessageSource 会加载指定路径下的多语言配置文件;当业务代码获取国际化消息时,框架会根据当前 Accept-Language 从对应配置文件/数据源中匹配消息键(Key),返回对应的消息值(Value)。

二、方式一:基于配置文件的 i18n 实现

2.1 环境准备

2.1.1 依赖配置

新建 SpringBoot 项目(推荐 2.7.x 或 3.2.x),核心依赖仅需 spring-boot-starter-web,无需额外依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 可选:简化配置文件编写(.yml) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
</dependencies>
2.1.2 目录结构

在 resources 目录下创建 i18n 文件夹,用于存放多语言配置文件,最终目录结构:

resources/
├── application.yml          # 核心配置
└── i18n/                    # 国际化配置文件目录
    ├── messages.properties       # 默认配置(无语言标识)
    ├── messages_zh_CN.properties # 简体中文
    ├── messages_zh_TW.properties # 繁体中文
    └── messages_en_US.properties # 英文

2.2 多语言配置文件编写

2.2.1 命名规则

配置文件命名必须遵循 basename_语言代码_国家代码.properties 规则:

  • basename:自定义前缀(如 messages),需在 application.yml 中配置。
  • 无语言标识的 messages.properties 为默认配置,当匹配不到指定 Locale 的配置时,会使用该文件内容。
2.2.2 配置文件内容
  1. 默认配置(messages.properties):兜底使用,建议与默认语言(简体中文)保持一致
# 通用提示
common.submit=提交
common.cancel=取消
# 用户相关
user.name=用户名
user.age=年龄
# 校验提示
validate.required.id=主键不能为空
validate.required.name=姓名不能为空
  1. 简体中文(messages_zh_CN.properties):
# 通用提示
common.submit=提交
common.cancel=取消
# 用户相关
user.name=用户名
user.age=年龄
# 校验提示
validate.required.id=主键不能为空
validate.required.name=姓名不能为空
  1. 繁体中文(messages_zh_TW.properties):
# 通用提示
common.submit=提交
common.cancel=取消
# 用户相关
user.name=使用者名稱
user.age=年齡
# 校验提示
validate.required.id=主鍵不能為空
validate.required.name=姓名不能為空
  1. 英文(messages_en_US.properties):
# 通用提示
common.submit=Submit
common.cancel=Cancel
# 用户相关
user.name=Username
user.age=Age
# 校验提示
validate.required.id=Primary key cannot be empty
validate.required.name=Name cannot be empty

注意:properties 文件默认编码为 ISO-8859-1,直接写中文会乱码!需将 IDE 的 properties 文件编码设置为 UTF-8(IDEA:Settings → File Encodings → Properties Files → 勾选 Transparent native-to-ascii conversion)。

2.3 SpringBoot 核心配置

在 application.yml 中配置国际化相关参数,指定配置文件路径、默认语言、编码等:

spring:
  # 国际化配置
  messages:
    basename: i18n/messages      # 配置文件路径(无需写.properties 后缀)
    encoding: UTF-8              # 解决中文乱码
    fallback-to-system-locale: false  # 禁用系统语言回退
    default-locale: zh_CN        # 默认语言:简体中文
    cache-duration: 3600s        # 配置文件缓存时间(生产建议设置)
  # Web 配置(可选,用于请求参数解析)
  web:
    locale: zh_CN

2.4 自定义语言解析器与拦截器

默认情况下,SpringBoot 仅支持从请求头 Accept-Language 获取 Locale,为了方便通过请求参数(如 ?Accept-Language=en-US)切换语言,需自定义 LocaleResolver 并注册拦截器。

2.4.1 自定义 LocaleResolver

创建 config/I18nConfig.java,实现 LocaleResolver 接口:

package com.example.i18n.config;

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.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.handler.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

/**
 * 国际化核心配置类(修改为 Header 拦截语言)
 */
@Configuration
public class I18nConfig implements WebMvcConfigurer {

    /**
     * 注册自定义 LocaleResolver(基于 Session 存储 Locale)
     * 替代默认的 AcceptHeaderLocaleResolver
     */
    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver resolver = new SessionLocaleResolver();
        // 设置默认语言:简体中文(与 application.yml 中保持一致)
        resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
        return resolver;
    }

    /**
     * 自定义拦截器:从 Accept-Language Header 解析并设置 Locale
     */
    @Bean
    public HandlerInterceptor localeHeaderInterceptor(LocaleResolver localeResolver) {
        return new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                // 1. 从请求头中获取语言标识(自定义 Header 名:Accept-Language,可根据需求修改)
                String acceptLanguage = request.getHeader("Accept-Language");
                // 2. 设置默认语言为空或者抛异常使用 Locale locale = Locale.SIMPLIFIED_CHINESE; // 默认语言// 默认:zh_CN
                Locale locale = Locale.SIMPLIFIED_CHINESE;
                // 3. 若 Header 中有值,则解析并设置 Accept-Language;无值则使用默认 Accept-Language
                if (acceptLanguage != null && !acceptLanguage.isEmpty()) {
                    try {
                        // 取第一个语言项(如 "zh-CN,en;q=0.8" → "zh-CN")
                        String primary = acceptLanguage.split(",")[0].trim();
                        // Spring 工具类能正确解析 "zh-CN"、"en" 等格式
                        locale = StringUtils.parseLocale(primary);
                    } catch (Exception e) {
                        // 解析失败则使用默认语言,不抛异常
                    }
                }
                // 使用容器中真实的 LocaleResolver 实例设置 Locale(存入 Session)
                localeResolver.setLocale(request, response, locale);
                return true;
            }
        };
    }

    /**
     * 注册拦截器到 Spring MVC 拦截器链
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeHeaderInterceptor(localeResolver()))
                .addPathPatterns("/**")
                .order(0); // 优先级最高
    }
}

关键说明:

  • SessionLocaleResolver:将 Locale 存储在 Session 中,一次切换后,后续请求无需重复传参。
  • localeHeaderInterceptor:拦截请求头 Header 中 Accept-Language 参数,自动更新当前 Locale(如 Accept-Language=zh-TW 会切换为繁体中文)。

2.5 国际化消息使用示例

2.5.1 工具类封装(推荐)

创建 utils/I18nUtils.java,封装获取国际化消息的方法,简化业务使用:

package com.example.i18n.utils;

import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Locale;

/**
 * 国际化工具类
 */
@Component
public class I18nUtils {

    @Resource
    private MessageSource messageSource;

    /**
     * 获取国际化消息(使用当前 Locale)
     * @param key 消息键
     * @return 消息值
     */
    public String getMessage(String key) {
        return getMessage(key, null, LocaleContextHolder.getLocale());
    }

    /**
     * 获取国际化消息(带参数)
     * @param key 消息键
     * @param args 参数数组(如消息为"你好{0}",args=new Object[]{"张三"})
     * @return 消息值
     */
    public String getMessage(String key, Object[] args) {
        return getMessage(key, args, LocaleContextHolder.getLocale());
    }

    /**
     * 手动指定 Locale 获取消息
     * @param key 消息键
     * @param args 参数数组
     * @param locale 语言标识
     * @return 消息值
     */
    public String getMessage(String key, Object[] args, Locale locale) {
        try {
            // 从 MessageSource 中获取消息,若未找到则返回 key 本身
            return messageSource.getMessage(key, args, locale);
        } catch (Exception e) {
            return key;
        }
    }
}

核心 API 说明:

  • LocaleContextHolder.getLocale():获取当前线程的 Locale(由 LocaleResolver 解析)。
  • messageSource.getMessage(key, args, locale):核心方法,参数说明:
    • key:消息键(如 user.name)。
    • args:消息参数(用于替换消息中的占位符,如 user.hello=你好{0})。
    • locale:指定语言标识。
2.5.2 控制器使用示例

创建 controller/I18nController.java,编写接口测试国际化效果:

package com.example.i18n.controller;

import com.example.i18n.utils.I18nUtils;
import org.springframework.web.bind.annotation.

目录

  1. 前言
  2. 一、国际化基础认知
  3. 1.1 核心概念
  4. 1.2 核心原理
  5. 二、方式一:基于配置文件的 i18n 实现
  6. 2.1 环境准备
  7. 2.1.1 依赖配置
  8. 2.1.2 目录结构
  9. 2.2 多语言配置文件编写
  10. 2.2.1 命名规则
  11. 2.2.2 配置文件内容
  12. 通用提示
  13. 用户相关
  14. 校验提示
  15. 通用提示
  16. 用户相关
  17. 校验提示
  18. 通用提示
  19. 用户相关
  20. 校验提示
  21. 通用提示
  22. 用户相关
  23. 校验提示
  24. 2.3 SpringBoot 核心配置
  25. 国际化配置
  26. Web 配置(可选,用于请求参数解析)
  27. 2.4 自定义语言解析器与拦截器
  28. 2.4.1 自定义 LocaleResolver
  29. 2.5 国际化消息使用示例
  30. 2.5.1 工具类封装(推荐)
  31. 2.5.2 控制器使用示例
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Stable Diffusion v1.5 部署指南:GPU 加速与 Web 服务启动
  • QoderWork:阿里推出的桌面级通用智能体助手
  • 飞书机器人对接 Claude Code,实现移动端 AI 编程助手
  • 零基础学微信小程序前端(原生JS):从0到1写第一个可交互页面
  • Flutter 底部导航与 TabBar 多页切换实战
  • Java 中间件:Dubbo 服务降级(Mock 机制)
  • 基于腾讯云 HAI 与 DeepSeek 快速搭建个人网页
  • Windows 系统安装与配置 Neo4j 图数据库
  • 基于 OpenClaw 与飞书搭建 AI 新闻推送机器人
  • 算法:双指针解决快乐数问题
  • Windows Server 2022/2025 搭建 IIS Web 服务器实验指南
  • Kali Linux 系统安装与基础配置指南
  • AIGC 时代的核心协议:深入理解 Model Context Protocol (MCP)
  • 哈希表原理与冲突解决详解
  • 任意文件读取漏洞的深入利用与敏感文件路径分析
  • Java 零基础入门:环境搭建、语法基础与实战指南
  • 前端未死,AI 只是技术进化的序章
  • OpenClaw 本地部署实战:Web 面板调试与大模型接入
  • ToDesk、顺网云与海马云部署 DeepSeek 实测对比
  • Flutter 三方库 flutter_dropzone 的鸿蒙化适配指南

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online