一.基于springboot的validator自定义校验
1.pom文件中的依赖。
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.项目目录结构。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190326134840662.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h1YWh1YXhpamk=,size_16,color_FFFFFF,t_70) 3.model中创建实体。 package com.example.demo.model;
import java.io.Serializable;
import java.util.Date;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotBlank;
import com.example.demo.validator.EnumValue;
@SuppressWarnings(“deprecation”)
public class User implements Serializable{
private static final long serialVersionUID = 2594274431751408585L;
/**
* 用户ID
*/
private Long id;
/**
* 登录密码
*/
@NotBlank(message = "登录密码不能为空")
private String pwd;
@NotBlank(message = "昵称不能为空")
@Length(min=1, max=64)
private String nickname;
@Pattern(regexp = "^1[3-9]\\d{9}$")
private String phone;
/**
* 账号状态
*/
@EnumValue(enumClass=UserStatusEnum.class, enumMethod="isValidName")
private String status;
private Date latestLoginTime;
private String latestLoginIp;
private Date createTime;
private Date updateTime;
/**
* 用户状态枚举
*/
public enum UserStatusEnum {
/**正常的*/
NORMAL,
/**禁用的*/
DISABLED,
/**已删除的*/
DELETED;
/**
* 判断参数合法性
*/
public static boolean isValidName(String name) {
for (UserStatusEnum userStatusEnum : UserStatusEnum.values()) {
if (userStatusEnum.name().equals(name)) {
return true;
}
}
return false;
}
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getLatestLoginTime() {
return latestLoginTime;
}
public void setLatestLoginTime(Date latestLoginTime) {
this.latestLoginTime = latestLoginTime;
}
public String getLatestLoginIp() {
return latestLoginIp;
}
public void setLatestLoginIp(String latestLoginIp) {
this.latestLoginIp = latestLoginIp;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
}
4.实体中使用的是注解来验证。以下对hibernate-validator中的部分注解进行描述:
5.在创建validaotr自定义校验规则
package com.example.demo.validator;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import org.assertj.core.util.Strings;
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValue.Validator.class)
public @interface EnumValue {
String message() default “{custom.value.invalid}”;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<? extends Enum<?>> enumClass();
String enumMethod();
class Validator implements ConstraintValidator<EnumValue, Object> {
private Class<? extends Enum<?>> enumClass;
private String enumMethod;
@Override
public void initialize(EnumValue enumValue) {
enumMethod = enumValue.enumMethod();
enumClass = enumValue.enumClass();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext arg1) {
if (value == null) {
return Boolean.TRUE;
}
if (enumClass == null || enumMethod == null) {
return Boolean.TRUE;
}
Class<?> valueClass = value.getClass();
try {
Method method = enumClass.getMethod(enumMethod, valueClass);
if (!Boolean.TYPE.equals(method.getReturnType()) && !Boolean.class.equals(method.getReturnType())) {
throw new RuntimeException(Strings.formatIfArgs("%s method return is not boolean type in the %s class", enumMethod, enumClass));
}
if(!Modifier.isStatic(method.getModifiers())) {
throw new RuntimeException(Strings.formatIfArgs("%s method is not static method in the %s class", enumMethod, enumClass));
}
Boolean result = (Boolean)method.invoke(null, value);
return result == null ? false : result;
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException | SecurityException e) {
throw new RuntimeException(Strings.formatIfArgs("This %s(%s) method does not exist in the %s", enumMethod, valueClass, enumClass), e);
}
}
}
}
在isValid方法中写自己的校验规则,判断传进来的参数是什么类型,以及你想要校验的参数是什么类型,添加一些校验规则。
6.在controller中写测试方法,测试校验。
controller中一定要写这个@Validated注解,否则之前写的校验规则一点用处都没有。