前言
公司在做国际化项目时需要匹配多语言环境,通过spring实现i18n国际化方便快捷
项目结构
src/
├── main/
│ ├── java/
│ │ └── com/example/i18ndemo/
│ │ ├── config/ # 配置类
│ │ ├── controller/ # 控制器
│ │ ├── service/ # 服务层
│ │ └── I18nDemoApplication.java # 启动类
│ └── resources/
│ ├── static/ # 静态资源
│ ├── templates/ # 模板文件
│ ├── messages.properties # 默认语言文件
│ ├── messages_en.properties # 英文
│ ├── messages_zh_CN.properties # 中文
│ └── application.properties # 应用配置
└── test/ # 测试代码
创建springboot项目
创建一个springboot项目。项目名称是I18nDemo
添加maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Thymeleaf (可选,用于前端模板) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 验证支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
初始化语言文件
在 resources
目录下创建以下文件:
messages.properties (默认)
welcome.message=Welcome
user.greeting=Hello, {0}
login.title=Login
messages_zh_CN.properties
welcome.message=欢迎
user.greeting=你好, {0}
login.title=登录
messages_ja.properties
welcome.message=ようこそ
user.greeting=こんにちは, {0}
login.title=ログイン
配置国际化支持
应用配置 (application.properties
)
# 国际化配置
spring.messages.basename=messages
spring.messages.encoding=UTF-8
spring.messages.fallback-to-system-locale=false
# Thymeleaf 配置 (如果使用)
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
创建配置类
普通的配置类支持通过url参数切换语言
package com.example.i18ndemo.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.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
@Configuration
public class I18nConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver slr = new SessionLocaleResolver();
slr.setDefaultLocale(Locale.ENGLISH); // 设置默认语言
return slr;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
lci.setParamName("lang"); // 通过URL参数切换语言
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(localeChangeInterceptor());
}
}
优化过的配置类,支持通过url和head传递国际化参数,推荐使用head方便快捷
此种方式传递中文的时候需要用zh-CN
Spring的
LocaleContextHolder
能自动处理zh_CN
和zh-CN
但底层
Locale.forLanguageTag()
仍然要求标准格式如果前端传的是
zh_CN,则后端可以直接替换下
localeStr = localeStr.replace('_', '-');
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.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
@Configuration
public class I18nConfig implements WebMvcConfigurer {
@Bean
public LocaleResolver localeResolver() {
SmartLocaleResolver resolver = new SmartLocaleResolver();
resolver.setDefaultLocale(Locale.ENGLISH);
return resolver;
}
public class SmartLocaleResolver implements LocaleResolver {
private Locale defaultLocale = Locale.ENGLISH;
@Override
public Locale resolveLocale(HttpServletRequest request) {
// 1. 优先检查 URL 参数(如 ?lang=zh_CN)
String langParam = request.getParameter("lang");
if (langParam != null && !langParam.isEmpty()) {
return Locale.forLanguageTag(langParam);
}
// 2. 如果没有 URL 参数,检查 Accept-Language 头
String acceptLanguage = request.getHeader("Accept-Language");
if (acceptLanguage != null && !acceptLanguage.isEmpty()) {
return request.getLocale();
}
// 3. 返回默认语言
return defaultLocale;
}
@Override
public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) {
// 如果需要动态修改语言,可以在这里实现
}
public void setDefaultLocale(Locale defaultLocale) {
this.defaultLocale = defaultLocale;
}
}
}
创建测试控制器
package com.example.i18ndemo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Locale;
@Controller
public class HomeController {
private final MessageSource messageSource;
@Autowired
public HomeController(MessageSource messageSource) {
this.messageSource = messageSource;
}
@GetMapping("/")
public String home(Model model) {
// 通过代码获取消息
String welcomeMsg = messageSource.getMessage(
"welcome.message",
null,
LocaleContextHolder.getLocale()
);
model.addAttribute("welcomeMsg", welcomeMsg);
return "home";
}
}
创建 Thymeleaf 模板
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title th:text="#{login.title}">Login</title>
</head>
<body>
<h1 th:text="${welcomeMsg}">Welcome</h1>
<!-- 直接使用消息 -->
<p th:text="#{user.greeting('John')}">Hello, User</p>
<!-- 语言切换链接 -->
<div>
<a href="?lang=en">English</a> |
<a href="?lang=zh-CN">中文</a> |
<a href="?lang=ja">日本語</a>
</div>
</body>
</html>
运行项目
启动主类
I18nDemoApplication
访问
http://localhost:8080
点击不同语言链接测试切换功能
扩展建议
数据库存储消息:对于大型项目,可以实现
MessageSource
接口从数据库加载消息前端框架集成:如果使用 Vue/React,可以创建 API 端点返回语言包
自动化测试:编写测试验证所有语言包是否完整
本地化日期/数字:使用 Spring 的
Formatter
体系实现
这样你就完成了一个基本的支持国际化的 Spring Boot 项目!