Spring Boot参数校验国际化核心是用键名(如user.name.notblank)替代注解中硬编码的message,并通过MessageSource从i18n/messages_*.properties加载多语言提示;需配置ResourceBundleMessageSource、setValidationMessageSource、AcceptHeaderLocaleResolver及全局异常处理器提取getDefaultMessage。

Spring Boot 中参数校验的国际化错误提示,核心是让 @NotBlank、@Size 等注解里的 message 属性不再写死中文或英文,而是通过键名(如 user.name.notblank)从多语言 properties 文件中动态加载。配置不复杂,但几个关键环节缺一不可。
1. 准备多语言资源文件
在 src/main/resources 下新建 i18n/ 目录,放入以下文件:
-
i18n/messages.properties(默认语言,建议用英文) -
i18n/messages_zh_CN.properties(中文简体) -
i18n/messages_en_US.properties(英文美国)
内容示例:
# messages_zh_CN.properties<br>user.name.notblank=用户名不能为空<br>user.age.min=年龄不能小于{0}注意:键名必须完全一致,值中可用 {0}、{1} 占位符,后续会被自动填充。
2. 配置 MessageSource 和 Validator
添加配置类,把消息源和校验器关联起来:
@Configuration<br>public class ValidationConfig {<br> @Bean<br> public MessageSource messageSource() {<br> ResourceBundleMessageSource source = new ResourceBundleMessageSource();<br> source.setBasename("i18n.messages"); // 对应文件路径<br> source.setDefaultEncoding("UTF-8");<br> return source;<br> }<br><br> @Bean<br> public LocalValidatorFactoryBean validator(MessageSource messageSource) {<br> LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();<br> bean.setValidationMessageSource(messageSource);<br> return bean;<br> }<br>}这一步最关键:没有 setValidationMessageSource,校验注解就无法读取国际化内容。
3. 在实体类中使用键名代替硬编码
修改 DTO 或请求对象字段上的注解,把 message 改成键名:
public class UserDTO {<br> @NotBlank(message = "user.name.notblank")<br> private String name;<br><br> @Min(value = 18, message = "user.age.min")<br> private Integer age;<br>}注意:message 值只是键,不是实际文本;占位符参数(如 @Min 的 value)会自动传入 {0},无需手动处理。
4. 配置区域解析器(可选但推荐)
让系统能根据请求头(如 Accept-Language: zh-CN)自动切换语言:
@Configuration<br>public class I18nConfig {<br> @Bean<br> public LocaleResolver localeResolver() {<br> AcceptHeaderLocaleResolver resolver = new AcceptHeaderLocaleResolver();<br> resolver.setDefaultLocale(Locale.ENGLISH);<br> return resolver;<br> }<br>}这样前端不需额外传参,浏览器语言变了,错误提示也跟着变。
5. 全局异常处理器统一返回格式
捕获 MethodArgumentNotValidException,提取已国际化的错误信息:
@RestControllerAdvice<br>public class GlobalExceptionHandler {<br> @ExceptionHandler(MethodArgumentNotValidException.class)<br> public ResultVO<?> handleValidation(MethodArgumentNotValidException e) {<br> String msg = e.getBindingResult()<br> .getFieldErrors()<br> .stream()<br> .map(FieldError::getDefaultMessage) // 此处拿到的就是翻译后的文本<br> .collect(Collectors.joining("; "));<br> return ResultVO.error(400, msg);<br> }<br>}确保 FieldError::getDefaultMessage 被调用,它才是走 MessageSource 查找后的真实提示。


















