You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过@ControllerAdvice实现Spring Validation错误消息本地化?

Spring Validation错误消息本地化(结合@ControllerAdvice)

要实现Spring Validation错误消息的本地化,配合@ControllerAdvice统一处理异常,只需按以下步骤操作:

1. 创建国际化资源文件

在src/main/resources下创建多语言的消息配置文件:

  • messages_en.properties(英文):
    javax.validation.constraints.Min.message=must be greater than or equal to {value}
    
  • messages_fr.properties(法语):
    javax.validation.constraints.Min.message=doit être supérieur ou égal à {value}
    

注意:{value}是占位符,会自动替换@Min注解中指定的数值(比如示例中的1)。

2. 配置Spring本地化组件

创建Spring配置类,注册LocaleResolver(解析请求的语言)和MessageSource(加载国际化资源):

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;

import java.util.Locale;

@Configuration
public class LocaleConfig {

    // 从请求的Accept-Language头解析语言
    @Bean
    public LocaleResolver localeResolver() {
        AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();
        resolver.setDefaultLocale(Locale.ENGLISH); // 默认英文
        return resolver;
    }

    // 加载国际化消息文件
    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages"); // 对应资源文件前缀
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
}

3. 用@ControllerAdvice统一处理验证异常

编写全局异常处理器,捕获参数验证异常,并根据当前请求的语言返回本地化消息:

import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@ControllerAdvice
public class GlobalExceptionHandler {

    private final MessageSource messageSource;

    // 构造注入MessageSource
    public GlobalExceptionHandler(MessageSource messageSource) {
        this.messageSource = messageSource;
    }

    // 处理@PathVariable、@RequestParam等的验证异常
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<Map<String, String>> handleConstraintViolation(ConstraintViolationException ex) {
        Map<String, String> errors = new HashMap<>();
        Set<ConstraintViolation<?>> violations = ex.getConstraintViolations();
        
        for (ConstraintViolation<?> violation : violations) {
            // 根据当前Locale获取本地化消息
            String message = messageSource.getMessage(
                    violation.getMessageTemplate(),
                    new Object[]{violation.getConstraintDescriptor().getAttributes().get("value")},
                    LocaleContextHolder.getLocale()
            );
            errors.put(violation.getPropertyPath().toString(), message);
        }
        return ResponseEntity.badRequest().body(errors);
    }
}

测试验证

  • 当请求头携带Accept-Language: en,传入id=-5时,返回:
    {"id":"must be greater than or equal to 1"}
    
  • 当请求头携带Accept-Language: fr,传入id=-5时,返回:
    {"id":"doit être supérieur ou égal à 1"}
    

内容的提问来源于stack exchange,提问作者Arahnid _

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 08:50:38