spring mvc 在拦截器、控制器和视图中获取和使用国际化区域信息的完整示例


在拦截器、控制器和视图中获取和使用国际化区域信息的完整示例


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. 测试流程
  1. 切换语言

    访问 /custom-locale 并携带 Locale 参数(如 ?lang=zh):

    bash 复制代码
    curl "http://localhost:8080/custom-locale?lang=zh" 
    # 输出:当前语言代码:zh_CN
  2. 控制器响应

    访问 /greeting 返回对应语言的消息:

    bash 复制代码
    curl "http://localhost:8080/greeting" 
    # 输出:你好!(若 Locale 为中文)
  3. 视图渲染

    访问 /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 localeLocaleResolver MessageSource 或直接返回 #{message} 返回国际化响应
视图(Thymeleaf) 自动继承请求的 Locale #{message.key} 语法 渲染多语言页面

5. 常见问题
  • Q:拦截器如何注入 MessageSource

    A:通过 @Autowired 注解注入,需确保拦截器是 Spring 管理的 Bean(如通过 WebMvcConfigurer 注册)。

  • Q:如何在 Thymeleaf 中传递动态参数?

    A:使用占位符语法 #{welcome.message({0})},并传递参数:

    java 复制代码
    model.addAttribute("name", "张三");
  • Q:如何在拦截器中修改 Locale

    A:通过 LocaleResolver.setLocale(request, response, newLocale)

    java 复制代码
    localeResolver.setLocale(request, response, Locale.GERMANY);

总结

通过上述代码示例,拦截器、控制器和视图均可无缝集成国际化功能。核心是利用 LocaleResolver 确定区域,结合 MessageSource 解析消息,最终在各层实现灵活的多语言支持。实际开发中,建议结合 LocaleChangeInterceptor 提供 URL 参数切换语言的能力,提升用户体验。

相关推荐
ByNotD0g9 小时前
Tomcat中的回显问题
java·tomcat
云澜哥哥9 小时前
MyBatis 实战指南:特殊符号处理与高效批量操作
java·jvm·mybatis
CRMEB9 小时前
电商项目中订单流程可以使用哪些设计模式?如何开发?
java·设计模式·gitee·开源·php·crmeb
CNAHYZ9 小时前
Apache HttpClient 配置 SSL 证书指南
java·spring boot·http
格鸰爱童话9 小时前
向AI学习项目技能(三)
java·人工智能·python·学习
weixin1997010801610 小时前
南网商城商品详情页前端性能优化实战
java·前端·性能优化
iPadiPhone10 小时前
Spring Boot 自动装配原理与 Starter 开发实战
java·spring boot·后端·spring·面试
SuGarSJL10 小时前
FakeSMTP-2.1.1使用
java·maven
码匠君10 小时前
首个基于 Spring Boot 4 的正式版发布!Dante Cloud 4.X 新特性全解析
java·spring boot·后端