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 参数切换语言的能力,提升用户体验。

相关推荐
码熔burning14 分钟前
【NIO番外篇】之组件 Channel
java·nio·channel
卡尔曼的BD SLAMer1 小时前
问题 | 针对SSM(Spring + Spring MVC + MyBatis)框架的去Spring MVC强化版学习路线
java·spring·mvc·mybatis
春生野草1 小时前
0413-多态、Object类方法、访问权限修饰符、装箱拆箱、128陷阱
java·开发语言
烁3471 小时前
每日一题(小白)暴力娱乐篇25
java·数据结构·算法·娱乐
烁3471 小时前
每日一题(小白)暴力娱乐篇26
java·开发语言·算法·娱乐
小白的一叶扁舟2 小时前
Java设计模式全解析(共 23 种)
java·开发语言·设计模式·springboot
kkkkatoq2 小时前
设计模式 四、行为设计模式(2)
java·开发语言·设计模式
peiwang2453 小时前
网页制作中的MVC和MVT
后端·mvc
隔壁小王攻城狮3 小时前
完整源码停车场管理系统,含新能源充电系统,实现了停车+充电一体化
java·开源·iot·停车场系统·新能源汽车充电·停车场管理系统源码
橘子青衫3 小时前
多线程编程探索:阻塞队列与生产者-消费者模型的应用
java·后端·架构