如何通过@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 _
相关产品推荐
相关产品推荐

