Skip to content

验证 (Validation)

默认情况下,如果类路径上存在 Bean Validation 实现(例如 Hibernate Validator),Spring 会注册 LocalValidatorFactoryBean 作为全局验证器(Validator),用于在控制器方法参数上配合 @Valid@Validated 使用。

自定义全局验证器

你可以自定义全局 Validator 实例:

java
@Configuration
public class WebConfiguration implements WebMvcConfigurer {

	@Override
	public Validator getValidator() {
		Validator validator = new OptionalValidatorFactoryBean();
		// 进行自定义配置...
		return validator;
	}
}
kotlin
@Configuration
class WebConfiguration : WebMvcConfigurer {

	override fun getValidator(): Validator {
		val validator = OptionalValidatorFactoryBean()
		// ...
		return validator
	}
}
xml
<mvc:annotation-driven validator="globalValidator"/>

局部验证器注册

除了全局验证器,你也可以在特定的控制器中注册 Validator 实现,这通常通过 @InitBinder 完成:

java
@Controller
public class MyController {

	@InitBinder
	public void initBinder(WebDataBinder binder) {
		binder.addValidators(new FooValidator());
	}
}
kotlin
@Controller
class MyController {

	@InitBinder
	fun initBinder(binder: WebDataBinder) {
		binder.addValidators(FooValidator())
	}
}

提示

如果你需要在其他地方注入 LocalValidatorFactoryBean,请创建一个 Bean 并用 @Primary 标记它,以避免与 MVC 配置中声明的 Bean 冲突。


补充教学

1. @Valid vs @Validated

  • @Valid: 源自标准的 JSR-303/JSR-380 (Bean Validation)。它可以用在方法参数、成员变量上。它不支持验证分组(Groups)。
  • @Validated: 由 Spring 提供。它是 @Valid 的增强版,最主要的区别在于它支持验证分组。此外,它还可以放在类级别(结合 @Service 等)来开启方法级别的参数验证。

2. 级联验证

如果要验证对象内部的列表或嵌套对象,必须在嵌套字段上添加 @Valid 注解,否则 Spring 只会验证顶层属性而忽略其内部成员。

3. 如何处理错误?

验证失败时,如果参数后面紧跟一个 BindingResult 参数,Spring 会将错误信息填充到其中供你手动处理。如果没有 BindingResult,Spring 会抛出 MethodArgumentNotValidException(对于 @RequestBody)或 BindException(对于表单提交),通常由全局异常处理器统一拦截。

Based on Spring Framework.