全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-18 6 分钟 ✍️ juanwangdev

Spring MVC 国际化消息

Spring MVC提供了完整的国际化支持,通过MessageSource实现多语言消息管理。

MessageSource配置

Java
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Bean
    public MessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasenames("i18n/messages");    // 资源文件基础名
        messageSource.setDefaultEncoding("UTF-8");
        messageSource.setCacheSeconds(3600);            // 缓存1小时
        return messageSource;
    }
}

资源文件结构

properties
src/main/resources/
├── i18n/
│   ├── messages.properties          # 默认语言
│   ├── messages_en.properties       # 英文
│   ├── messages_zh.properties       # 中文
│   ├── messages_zh_CN.properties    # 简体中文
│   └── messages_ja.properties       # 日文

资源文件内容

Java
# messages.properties(默认)
welcome.message=Welcome
error.required={0} is required
error.invalid={0} format is invalid
user.profile=User Profile

# messages_zh_CN.properties(简体中文)
welcome.message=欢迎访问
error.required={0}不能为空
error.invalid={0}格式不正确
user.profile=用户资料

# messages_en.properties(英文)
welcome.message=Welcome
error.required={0} is required
error.invalid={0} format is invalid
user.profile=User Profile

LocaleResolver配置

Java
@Bean
public LocaleResolver localeResolver() {
    SessionLocaleResolver resolver = new SessionLocaleResolver();
    resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
    return resolver;
}

LocaleChangeInterceptor

Java
@Override
public void addInterceptors(InterceptorRegistry registry) {
    LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
    localeInterceptor.setParamName("lang");    // 通过lang参数切换语言

    registry.addInterceptor(localeInterceptor)
        .addPathPatterns("/**");
}

在Controller中使用

Java
@RestController
public class UserController {

    @Autowired
    private MessageSource messageSource;

    @GetMapping("/welcome")
    public String welcome() {
        Locale locale = LocaleContextHolder.getLocale();
        return messageSource.getMessage("welcome.message", null, locale);
    }

    @GetMapping("/error")
    public String errorExample() {
        Locale locale = LocaleContextHolder.getLocale();
        String[] args = {"用户名"};
        return messageSource.getMessage("error.required", args, locale);
    }
}

在Service中使用

HTML
@Service
public class UserService {

    @Autowired
    private MessageSource messageSource;

    public void validateUser(UserDTO dto) {
        Locale locale = LocaleContextHolder.getLocale();

        if (dto.getUsername() == null || dto.getUsername().isEmpty()) {
            String message = messageSource.getMessage(
                "error.required",
                new Object[]{"用户名"},
                locale
            );
            throw new ValidationException(message);
        }
    }
}

在视图模板中使用

Thymeleaf

jsp
<p th:text="#{welcome.message}">Welcome</p>
<p th:text="#{error.required(${fieldName})}">Field is required</p>

JSP

Java
<spring:message code="welcome.message"/>
<spring:message code="error.required" arguments="用户名"/>

国际化工具类

Java
@Component
public class MessageUtils {

    private static MessageSource messageSource;

    @Autowired
    public void setMessageSource(MessageSource messageSource) {
        MessageUtils.messageSource = messageSource;
    }

    public static String getMessage(String code) {
        return getMessage(code, null);
    }

    public static String getMessage(String code, Object[] args) {
        Locale locale = LocaleContextHolder.getLocale();
        return messageSource.getMessage(code, args, locale);
    }

    public static String getMessage(String code, Object[] args, Locale locale) {
        return messageSource.getMessage(code, args, locale);
    }

    public static String getMessage(String code, String defaultMessage) {
        Locale locale = LocaleContextHolder.getLocale();
        return messageSource.getMessage(code, null, defaultMessage, locale);
    }
}

AcceptHeaderLocaleResolver

根据HTTP请求头Accept-Language自动确定语言:

Java
@Bean
public LocaleResolver localeResolver() {
    AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
    resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
    return resolver;
}

CookieLocaleResolver

使用Cookie存储用户语言偏好:

Java
@Bean
public LocaleResolver localeResolver() {
    CookieLocaleResolver resolver = new CookieLocaleResolver();
    resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
    resolver.setCookieName("lang");
    resolver.setCookieMaxAge(365 * 24 * 60 * 60);    // 1年
    return resolver;
}

固定LocaleResolver

始终使用固定语言:

Java
@Bean
public LocaleResolver localeResolver() {
    FixedLocaleResolver resolver = new FixedLocaleResolver();
    resolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
    return resolver;
}

LocaleResolver对比

Resolver语言来源特点
SessionLocaleResolverSession用户可切换,会话级别
CookieLocaleResolverCookie用户可切换,持久化
AcceptHeaderLocaleResolverAccept-Language头自动识别,无法手动切换
FixedLocaleResolver固定配置系统固定语言

动态切换语言

properties
@RestController
@RequestMapping("/api/lang")
public class LanguageController {

    @Autowired
    private LocaleResolver localeResolver;

    @PostMapping("/change")
    public void changeLanguage(HttpServletRequest request,
                               HttpServletResponse response,
                               @RequestParam String lang) {
        Locale locale = new Locale(lang);
        localeResolver.setLocale(request, response, locale);
    }
}

校验消息国际化

Java
# ValidationMessages_zh_CN.properties
javax.validation.constraints.NotNull.message=不能为空
javax.validation.constraints.Size.message=长度必须在{min}和{max}之间
javax.validation.constraints.Email.message=邮箱格式不正确
text
@Data
public class UserDTO {
    @NotNull(message = "{user.name.required}")
    private String username;

    @Size(min = 6, max = 20, message = "{user.password.size}")
    private String password;

    @Email(message = "{user.email.invalid}")
    private String email;
}

要点总结

  • MessageSource管理多语言资源文件
  • LocaleResolver确定当前语言环境
  • LocaleChangeInterceptor支持动态切换语言
  • LocaleContextHolder获取当前Locale
  • 资源文件命名格式:messages_语言_国家.properties
  • 校验消息支持国际化配置

📝 发现内容有误?点击此处直接编辑

← 上一篇 Spring MVC 分组校验
下一篇 → Spring MVC 数据格式化
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库