在拦截器、控制器和视图中获取和使用国际化区域信息的完整示例
1. 核心组件代码示例
1.1 配置类(Spring Boot)
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import java.util.Locale;
@Configuration
public class I18nConfig {
// 配置 MessageSource:加载国际化消息文件
@Bean
public ReloadableResourceBundleMessageSource messageSource() {
ReloadableResourceBundleMessageSource source = new ReloadableResourceBundleMessageSource();
source.setBasenames("classpath:i18n/messages"); // 消息文件前缀
source.setDefaultEncoding("UTF-8");
source.setCacheSeconds(60); // 60秒后重新加载
return source;
}
// 配置 SessionLocaleResolver:通过 Session 存储 Locale
@Bean
public SessionLocaleResolver localeResolver() {
SessionLocaleResolver resolver = new SessionLocaleResolver();
resolver.setDefaultLocale(Locale.US); // 默认语言为英语
return resolver;
}
}
1.2 拦截器(获取并使用 Locale)
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.i18n.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
public class I18nInterceptor implements HandlerInterceptor {
@Autowired
private LocaleResolver localeResolver;
@Autowired
private MessageSource messageSource;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 从 Session 中获取当前 Locale
Locale currentLocale = localeResolver.resolveLocale(request);
System.out.println("当前语言:" + currentLocale.getLanguage());
// 根据 Locale 获取国际化消息(示例:记录日志)
String logMessage = messageSource.getMessage("log.request", null, currentLocale);
System.out.println(logMessage); // 输出:请求已接收(假设消息键 "log.request" 对应不同语言)
return true;
}
}
1.3 控制器(使用 Locale 参数)
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.LocaleResolver;
import javax.servlet.http.HttpServletRequest;
import java.util.Locale;
@RestController
public class I18nController {
@Autowired
private MessageSource messageSource;
// 方法参数直接注入 Locale
@GetMapping("/greeting")
public String greeting(Locale locale) {
// 根据 Locale 获取国际化消息
String greeting = messageSource.getMessage("greeting.message", null, locale);
return greeting; // 返回 "Hello!"(英语)或 "你好!"(中文)
}
// 通过 LocaleResolver 获取 Locale(示例:自定义逻辑)
@GetMapping("/custom-locale")
public String customLocale(HttpServletRequest request) {
LocaleResolver resolver = (LocaleResolver) request.getAttribute("localeResolver");
Locale currentLocale = resolver.resolveLocale(request);
return "当前语言代码:" + currentLocale.toString();
}
}
1.4 视图(Thymeleaf 模板)
html
<!-- templates/greeting.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>国际化示例</title>
</head>
<body>
<!-- 直接引用消息键,Spring 自动根据 Locale 解析 -->
<h1 th:text="#{greeting.title}">默认标题</h1>
<p th:text="#{greeting.message}">默认消息</p>
<!-- 动态参数示例 -->
<p th:text="#{welcome.message(${name})}">欢迎信息</p>
</body>
</html>
1.5 国际化消息文件
properties
# messages.properties(默认英语)
log.request=Request received
greeting.title=Greeting Page
greeting.message=Hello!
# messages_zh_CN.properties(中文)
log.request=请求已接收
greeting.title=问候页面
greeting.message=你好!
# messages_es.properties(西班牙语)
log.request=Petición recibida
greeting.title=Página de Saludo
greeting.message=¡Hola!
2. 测试流程
-
切换语言 :
访问
/custom-locale
并携带Locale
参数(如?lang=zh
):bashcurl "http://localhost:8080/custom-locale?lang=zh" # 输出:当前语言代码:zh_CN
-
控制器响应 :
访问
/greeting
返回对应语言的消息:bashcurl "http://localhost:8080/greeting" # 输出:你好!(若 Locale 为中文)
-
视图渲染 :
访问
/greeting.html
时,Thymeleaf 自动根据Locale
渲染对应语言的页面。
3. 关键代码说明
- 拦截器 :
- 通过
LocaleResolver
获取当前Locale
,并使用MessageSource
解析日志消息。
- 通过
- 控制器 :
- 直接注入
Locale
参数,或通过HttpServletRequest
获取LocaleResolver
。
- 直接注入
- 视图 :
- 使用
#{message.key}
语法,Spring 自动注入当前Locale
的消息。
- 使用
4. 总结表格:组件获取与使用方法
组件 | 获取 Locale 的方式 |
使用国际化消息的方法 | 示例 |
---|---|---|---|
拦截器 | LocaleResolver.resolveLocale(request) |
MessageSource.getMessage(key, args, locale) |
记录日志、权限校验 |
控制器 | 方法参数 Locale locale 或 LocaleResolver |
MessageSource 或直接返回 #{message} |
返回国际化响应 |
视图(Thymeleaf) | 自动继承请求的 Locale |
#{message.key} 语法 |
渲染多语言页面 |
5. 常见问题
-
Q:拦截器如何注入
MessageSource
?A:通过
@Autowired
注解注入,需确保拦截器是 Spring 管理的 Bean(如通过WebMvcConfigurer
注册)。 -
Q:如何在 Thymeleaf 中传递动态参数?
A:使用占位符语法
#{welcome.message({0})}
,并传递参数:javamodel.addAttribute("name", "张三");
-
Q:如何在拦截器中修改
Locale
?A:通过
LocaleResolver.setLocale(request, response, newLocale)
:javalocaleResolver.setLocale(request, response, Locale.GERMANY);
总结
通过上述代码示例,拦截器、控制器和视图均可无缝集成国际化功能。核心是利用 LocaleResolver
确定区域,结合 MessageSource
解析消息,最终在各层实现灵活的多语言支持。实际开发中,建议结合 LocaleChangeInterceptor
提供 URL 参数切换语言的能力,提升用户体验。