校验框架介绍
JSR303 是一套JavaBean参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们JavaBean的属性上面,就可以在需要校验的时候进行校验了。注解如下:
Hibernate validator 在JSR303的基础上对校验注解进行了扩展,扩展注解如下:
Spring validtor 同样扩展了jsr303,并实现了方法参数和返回值的校验
Spring 提供了MethodValidationPostProcessor类,用于对方法的校验
代码实现
添加JAR包依赖
在pom.xml中添加如下依赖:
<!--jsr 303--> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <!-- hibernate validator--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.2.0.Final</version> </dependency>
最简单的参数校验
1、Model 中添加校验注解
public class Book { private long id; /** * 书名 */ @NotEmpty(message = "书名不能为空") private String bookName; /** * ISBN号 */ @NotNull(message = "ISBN号不能为空") private String bookIsbn; /** * 单价 */ @DecimalMin(value = "0.1",message = "单价最低为0.1") private double price; // getter setter ....... }
2、在controller中使用此校验
/** * 添加Book对象 * @param book */ @RequestMapping(value = "/book", method = RequestMethod.POST) public void addBook(@RequestBody @Valid Book book) { System.out.println(book.toString()); }
当访问这个post接口时,如果参数不符合Model中定义的话,程序中就回抛出400异常,并提示错误信息。
自定义校验注解
虽然jSR303和Hibernate Validtor 已经提供了很多校验注解,但是当面对复杂参数校验时,还是不能满足我们的要求,这时候我们就需要 自定义校验注解。
下面以“List数组中不能含有null元素”为实例自定义校验注解
1、注解定义如下:
package com.beiyan.validate.annotation; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * 自定义参数校验注解 * 校验 List 集合中是否有null 元素 */ @Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Constraint(validatedBy = ListNotHasNullValidatorImpl.class)////此处指定了注解的实现类为ListNotHasNullValidatorImpl public @interface ListNotHasNull { /** * 添加value属性,可以作为校验时的条件,若不需要,可去掉此处定义 */ int value() default 0; String message() default "List集合中不能含有null元素"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; /** * 定义List,为了让Bean的一个属性上可以添加多套规则 */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER}) @Retention(RUNTIME) @Documented @interface List { ListNotHasNull[] value(); } }
2、注解实现类:
package com.beiyan.validate.annotation; import org.springframework.stereotype.Service; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.List; /** * 自定义注解ListNotHasNull 的实现类 * 用于判断List集合中是否含有null元素 */ @Service public class ListNotHasNullValidatorImpl implements ConstraintValidator<ListNotHasNull, List> { private int value; @Override public void initialize(ListNotHasNull constraintAnnotation) { //传入value 值,可以在校验中使用 this.value = constraintAnnotation.value(); } public boolean isValid(List list, ConstraintValidatorContext constraintValidatorContext) { for (Object object : list) { if (object == null) { //如果List集合中含有Null元素,校验失败 return false; } } return true; } }
3、model添加注解:
public class User { //其他参数 ....... /** * 所拥有的书籍列表 */ @NotEmpty(message = "所拥有书籍不能为空") @ListNotHasNull(message = "List 中不能含有null元素") @Valid private List<Book> books; //getter setter 方法....... }
使用方法同上,在在需要校验的Model上面加上@Valid 即可
分组验证
对同一个Model,我们在增加和修改时对参数的校验也是不一样的,这个时候我们就需要定义分组验证,步骤如下
1、定义两个空接口,分别代表Person对象的增加校验规则和修改校验规则
/** * 可以在一个Model上面添加多套参数验证规则,此接口定义添加Person模型新增时的参数校验规则 */ public interface PersonAddView { } /** * 可以在一个Model上面添加多套参数验证规则,此接口定义添加Person模型修改时的参数校验规则 */ public interface PersonModifyView { }
2、Model上添加注解时使用指明所述的分组
public class Person { private long id; /** * 添加groups 属性,说明只在特定的验证规则里面起作用,不加则表示在使用Deafault规则时起作用 */ @NotNull(groups = {PersonAddView.class, PersonModifyView.class}, message = "添加、修改用户时名字不能为空", payload = ValidateErrorLevel.Info.class) @ListNotHasNull.List({ @ListNotHasNull(groups = {PersonAddView.class}, message = "添加上Name不能为空"), @ListNotHasNull(groups = {PersonModifyView.class}, message = "修改时Name不能为空")}) private String name; @NotNull(groups = {PersonAddView.class}, message = "添加用户时地址不能为空") private String address; @Min(value = 18, groups = {PersonAddView.class}, message = "姓名不能低于18岁") @Max(value = 30, groups = {PersonModifyView.class}, message = "姓名不能超过30岁") private int age; //getter setter 方法...... }
3、启用校验
此时启用校验和之前的不同,需要指明启用哪一组规则
/** * 添加一个Person对象 * 此处启用PersonAddView 这个验证规则 * 备注:此处@Validated(PersonAddView.class) 表示使用PersonAndView这套校验规则,若使用@Valid 则表示使用默认校验规则, * 若两个规则同时加上去,则只有第一套起作用 */ @RequestMapping(value = "/person", method = RequestMethod.POST) public void addPerson(@RequestBody @Validated({PersonAddView.class, Default.class}) Person person) { System.out.println(person.toString()); } /** * 修改Person对象 * 此处启用PersonModifyView 这个验证规则 */ @RequestMapping(value = "/person", method = RequestMethod.PUT) public void modifyPerson(@RequestBody @Validated(value = {PersonModifyView.class}) Person person) { System.out.println(person.toString()); }
Spring validator 方法级别的校验
JSR和Hibernate validator的校验只能对Object的属性进行校验,不能对单个的参数进行校验,spring 在此基础上进行了扩展,添加了MethodValidationPostProcessor拦截器,可以实现对方法参数的校验,实现如下:
1、实例化MethodValidationPostProcessor
@Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); }
2、在所要实现方法参数校验的类上面添加@Validated,如下
@RestController @Validated public class ValidateController { }
3、在方法上面添加校验规则:
@RequestMapping(value = "/test", method = RequestMethod.GET) public String paramCheck(@Length(min = 10) @RequestParam String name) { System.out.println(name); return null; }
当方法上面的参数校验失败,spring 框架就回抛出异常
{ "timestamp": 1476108200558, "status": 500, "error": "Internal Server Error", "exception": "javax.validation.ConstraintViolationException", "message": "No message available", "path": "/test" }
从此可以优雅的对参数进行校验了
写在后面的话:
本篇文章只列举了常用的几种校验方法,其实关于校验的内容还有很多:
校验信息的国际化显示,
组合参数校验,
message中使用EL表达式,
将校验信息绑定到ModelAndView等,这里就不一一列出了,下面这几篇文章写的也不错,读者可以参考:
将校验信息绑定到ModelAndView http://www.voidcn.com/blog/983836259/article/p-5794496.html
集成Bean Validation 1.1(JSR-349)到SpringMVC https://my.oschina.net/qjx1208/blog/200946
本文的全部代码已上传开源中国git仓库: http://git.oschina.net/beiyan/Validate
相关推荐
Maven坐标:jakarta.validation:jakarta.validation-api:2.0.2; 标签:api、jakarta、validation、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 ...
Maven坐标:jakarta.validation:jakarta.validation-api:2.0.1; 标签:jakarta、validation、api、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容...
Bean Validation是Java平台上用于对象验证的一种标准,旨在提供一种简单而强大的方式来确保Java Bean对象的正确性和完整性。本规范文档深入解析了Bean Validation的各个方面,包括其目标、版本信息、核心概念以及...
- **JSR 303/JSR 349**:Bean Validation 1.0和1.1是作为JSR(Java Specification Request)发布的,分别为JSR 303和JSR 349,适用于Java EE环境。 - **Hibernate Validator**:它是Bean Validation的参考实现,同时...
Bean Validation是Java世界中一种强大的数据验证框架,它允许开发者在模型对象(Bean)上定义约束,以便在运行时进行验证。这个框架的核心是JSR 303和JSR 349标准,它提供了统一的方式来处理业务逻辑中的数据验证,...
《Bean+Validation中文参考手册》是一份详尽的指南,旨在介绍Java EE 6中Bean Validation规范(JSR 303)的核心概念、用法及其实现细节。Bean Validation是一个强大的框架,用于在Java应用程序中对Java Bean对象的...
1. **约束注解**:Bean Validation提供了一系列预定义的注解,如`@NotNull`, `@Size`, `@Email`等,可以直接用于bean的字段上,声明验证规则。 2. **自定义约束**:除了预定义的注解,你还可以创建自己的约束注解,...
java.lang.NoClassDefFoundError: javax/validation/valueextraction/ValueExtractorDeclarationException 今天部署环境遇到这个问题,查了好长时间终于解决了; 问题原因: 由于jar包hibernate-validator、...
Maven坐标:jakarta.validation:jakarta.validation-api:2.0.1; 标签:jakarta、validation、api、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 ...
Bean Validation 规范对 Java Bean 的验证流程如下:在实际使用中调用 Validator.validate(JavaBeanInstance) 方法后,Bean Validation 会查找在 JavaBeanInstance上所有的约束声明,对每一个约束调用对应的约束验证...
BeanValidation(jar,英文手册,中文手册)合集BeanValidation(jar,英文手册,中文手册)合集.rarBeanValidation(jar,英文手册,中文手册)合集.rarBeanValidation(jar,英文手册,中文手册)合集.rarBeanValidation(jar,英文...
在Java开发中,Bean Validation是用于验证对象属性的框架,它提供了一种标准的方式来约束和验证Java类的字段。Bean Validation允许开发者定义一组规则,这些规则会在数据绑定到对象时自动执行,确保输入数据的正确性...
2. **Bean Validation**:Bean Validation(JSR 303/349)是Java中的一种标准验证框架,它允许开发者通过注解来定义实体属性的验证规则。例如,`@NotNull`、`@Size(min=, max=)`等,这些注解可以直接应用在字段上,...
Maven坐标:jakarta.validation:jakarta.validation-api:2.0.2; 标签:api、jakarta、validation、jar包、java、中英对照文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容...
绍Java EE 6核心特征:Bean Validation解析
Maven坐标:javax.validation:validation-api:2.0.1.Final; 标签:javax、api、validation、jar包、java、API文档、中英对照版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档...
### Java EE 6 Bean Validation:实体验证元数据模型与API #### 概述 Java EE 6中的Bean Validation(JSR 303)作为一项核心功能,为开发者提供了一个强大的实体验证框架。该框架定义了一种元数据模型以及一个API...
Maven坐标:javax.validation:validation-api:2.0.1.Final; 标签:javax、api、validation、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 ...
Java Validation A lib to make validations on java... compile 'com.github.brunodles:java-validation:{latest version}' } Take a look into (releases)[https://github.com/brunodles/java-validation/releases]