前端的数据校验都是辣鸡!后端天下第一!

很多时候我们后端需要前端传数据过来, 比如注册, 修改用户名, 修改密码等等。很可能有些用户就喜欢搞事, 喜欢发一大堆乱七八糟的数据到后端来, 甚至有些前端老哥甚至都不做校验, 简直气死人。所以我们后端必须自己做校验。这节介绍一下如何优雅地做数据校验。

做数据校验还是有原则的, 只有一条:不要相信前端传过来的任何数据。

如果想完美地贯彻原则, 理论上来说就应该让前端那边少传数据过来, 有些的东西能查的就自己查出来。

常用的数据校验like this:

/**
 * 判断对象是否不为空
 * @param object
 * @return
 */
public static boolean isEmpty (Object object) {
	if ("".equals(object) || object == null) {
		return false;
	}
	return true;
}
/**
 * 判断字符串是否不为空
 * @param str
 * @return
 */
public static boolean isEmpty (String str) {
	if ("".equals(str) || str == null) {
		return false;
	}
	return true;
}
/**
 * 判断Integer是否不为空
 * @param i
 * @return
 */
public static boolean isEmpty (Integer i) {
	if ("".equals(i) || i == null) {
		return false;
	}
	return true;
}

写个Util类, 然后每次校验数据都要调用它的方法, 像这样一次又一次去判断实在是太不优雅了, 甚至于有的接口就那么十来行代码, 校验语句就要用一半,这样写出来的代码是不会好看的。下面我们看一下JSR303。

JSR303是JAVA管理委员会定制的一种规范, 是对关于Bean Validation(对javabean进行验证)的一个接口, 它是没有具体实现的。但有一个现成的已经实现了JSR303的框架Hibernate Validator我们可以在SpringBoot中直接使用。

下表介绍Bean Validation中的注解及作用:


1.Bean Validation中内置的注解

注解

作用

@Null

被注解的元素必须为 null

@NotNull

被注解的元素必须不为 null

@AssertTrue

被注解的元素必须为 true

@AssertFalse

被注解的元素必须为 false

@Min(value)

被注解的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value)

被注解的元素必须是一个数字,其值必须小于等于指定的最大值

@DecimalMin(value)

被注解的元素必须是一个数字,其值必须大于等于指定的最小值

@DecimalMax(value)

被注解的元素必须是一个数字,其值必须小于等于指定的最大值

@Size(max, min)

被注解的元素的大小必须在指定的范围内

@Digits (integer, fraction)

被注解的元素必须是一个数字,其值必须在可接受的范围内

@Past

被注解的元素必须是一个过去的日期

@Future

被注解的元素必须是一个将来的日期

@Pattern(value)

被注解的元素必须符合指定的正则表达式

@Valid

级联验证(Bean中Bean是不能为空的)




2.Hibernate Validator附加的注解

注解

作用

@Email

被注解的元素必须是电子邮箱地址

@Length

被注解的字符串的大小必须在指定的范围内

@NotEmpty

被注解的字符串的必须非空

@Range

被注解的元素必须在合适的范围内




3.按照类型来分类

类型

注解

任何类型

Null, NotNull

布尔型

AssertTrue, AssertFalse

字符串

NotBlank, Pattern, Size, Email, DecimalMax, DecimalMin, Digits

数值

DecimalMax, DecimalMin, Digits, Max, Min, Negative, NegativeOrZero, Positive, PositiveOrZero

集合/Map/List

NotEmpty, Size

日期

Future, Past, FutureOrPresent, PastOrPresent




下面搞几个例子

@NotNull  // 虽然限制了students不能为空, 但它并不能限制students里的每一个元素, 如果集合中有几个为Null的对象, 也是可以通过验证的
private List<Student> students;
@NotNull
@Valid    // 级联验证做到了限制students里的每一个元素, 但这样会使代码可读性降低
private List<Student> students;
@NotNull  // 所以, 为了保证可读性, 一般用于下面这种写法
private List<@Valid Student> students;
@NotNull  // 这行表示strings此集合不能为空
@Size(min = 1)   // 这行表示strings此集合的大小至少要为1
private List<@Size(min = 10) @NotNull String> strings;
// 集合里的Size和NotNull注解, 表示约束了集合中的每个String不能为空, 且长度至少是10

需要注意的是, 如果你在父类中约束了某些属性, 那么这些约束在子类中同样有效。