本文为转载,转载地址为:https://www.cnblogs.com/beiyan/p/5946345.html。
前端基础校验过后,后端同样需要对参数校验,以保证代码的健壮性。本文主要介绍如何使用注解的方式优雅的校验参数。包括以下两个组成部分:
- JSR303
- Hibernate Validator
校验框架介绍
JSR303 是一套JavaBean参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们JavaBean的属性上面,就可以在需要校验的时候进行校验了。注解如下:
@Null | 被注释的元素必须为null |
@NotNull | 与@Null相反,被注释的元素不能为null |
@AssertTrue | 被注释的元素必须为true |
@AssertFalse | 被注释的元素必须为false |
@Min(value) | 被注释的元素必须是数字,且其值必须大于等于指定的最小值value |
@Max(value) | 被注释的元素必须是数字,且其值必须小于等于指定的最小值value |
@DecimalMin(value) | 被注释的元素必须是数字,且其值必须大于等于指定的最小值value |
@DecimalMax(value) | 被注释的元素必须是数字,且其值必须小于等于指定的最小值value |
@Size(max, min) | 被注释的元素大小在其规定的范围min~max内 |
@Digits(integer, fraction) | 被注释的元素必须是数字,与@Min相同,规定整数部分与小数部分的最小值 |
@Past | 被注释的元素必须是一个过去的日期 |
@Future | 被注释的元素必须是一个未来的日期 |
@Pattern(regex) | 被注释的元素必须符合正则表达式regex要求 |
Hibernate validator 在JSR303的基础上对校验注解进行了扩展,扩展注解如下:
被注释的元素必须是电子邮箱 | |
@Length | 被注释的元素长度必须在规定长度内 |
@NotEmpty | 被注释的元素必须非空 |
@Range | 被注释的元素必须在合理区间内 |
Spring validtor 同样扩展了jsr303,并实现了方法参数和返回值的校验,Spring 提供了MethodValidationPostProcessor类,用于对方法的校验。
代码实现
添加JAR包依赖:
<!--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异常,并提示错误信息。
自定义校验注解
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 即可
关于分组校验、Spring validator 方法级别的校验使用说明,请参考原文。
最后再次附上转载地址: https://www.cnblogs.com/beiyan/p/5946345.html。