对于前端来的数据,后端难免要进行合法性校验,这里可以采用springboot自带的Validated注解来实现,详细方法如下:
实体类:
public class User implements Serializable {
// @NotNull(message = "id can not be null")
private Integer id;
private String name;
@NotEmpty(message = "username can not be empty")
@Length(max = 40, min = 5, message = "username length must between 5 and 10")
private String username;
@Email
private String email;
//@Pattern(regexp = "^((13[0-9])|(15[^4,\\\\D])|(18[0,5-9]))\\\\d{8}$",
//message = "phone number illegal")
@Phone//自定义的注解
private String phone;
private Integer latest;
@NotEmpty(message = "passwd can not be empty")
@Length(max = 42, min = 5, message = "password lenth must between 5 and 42")
private String passwd;
private byte isDel;//默认值为0
private Timestamp lastAlter;
}
再在对应的web接口添加@Validated注解即可:
在校验不通过的时候,springboot会抛MethodArgumentNotValidException异常,直接把异常信息给客户端不友好,我们可以使用springboot的全局异常捕获来处理此异常,代码如下:
对于简单参数的非空等校验可以使用Spring提供的Assert类,参考博客:https://blog.csdn.net/qq_41633199/article/details/105165740。有时候springboot自带注解的可能不能满足我们的使用,这时我们可以自己实现一个注解与校验逻辑来进行加强,方式如下:
1:先新增一个注解:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint( validatedBy = PhoneConstraint.class)
//指定该注解在对应的属性上可以重复使用
@Repeatable(value = Phone.List.class)
public @interface Phone {
String message() default "tfq.validator.constraints.phone.message";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface List{
Phone[] value();
}
}
注解的groups()与payload()的作用可以参考这篇文章:https://reflectoring.io/bean-validation-with-spring-boot/
以及https://blog.csdn.net/blueheart20/article/details/88817754
再新增校验类PhoneConstraint.java,引用springboot的一个接口,以实现我们的校验逻辑以及确保校验类能被springboot加载到。
public final class PhoneConstraint implements ConstraintValidator<Phone, Object> {
private static final Pattern phonePattern = Pattern.compile("^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$");
{
System.out.println("自定义直接被调用了");
}
@Override
public void initialize(Phone constraintAnnotation) {}
@Override
public boolean isValid(Object phone, ConstraintValidatorContext constraintValidatorContext) {
String phoneStr = "";
if (phone instanceof String || phone instanceof Number){
phoneStr = String.valueOf(phone);
} else {
return false;
}
if (phoneStr == null || "".equals( phoneStr.trim() )){
return true;
}
Matcher phoneMatcher = phonePattern.matcher(phoneStr);
return phoneMatcher.matches();
}
这里的实现类不需要申明为bean,在第一次需要校验的时候,springboot会加载此类,生成一个此类的对象,后续校验直接通过原对象调用方法进行校验,就是说默认是单例的。