参数校验在后端开发中可以说是天天见了,天天写if-else想必也写烦了吧,那就换个口味,使用注解来实现参数校验吧。 主要用到的类和注解都在javax.validation包下。先来个示例:
import com.holic.blog.entity.CommonReq;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.validation.Valid;
@Controller
@RequestMapping("/test")
public class DemoController {
@GetMapping("/valid")
public String test(@RequestBody @Valid CommonReq req, BindingResult result) {
if (result.hasErrors()) {
throw new RuntimeException("参数校验不通过");
}
return "";
}
}
没错,这真的只是个示例,甚至还有点过于简单,但是能说明问题就够了。 请求先到达Controller,校验是在这里完成的:@Valid注解紧靠在需要进行校验的参数前面,告诉SpringBoot我要校验这个参数;result参数紧跟在要被校验的参数的后面,它是用来保存校验结果的,注意被校验对象和result之间不能有别的参数,否则校验结果不能保存到result中。怎么完成校验呢,肯定要进到对象里边:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.Valid;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonReq {
@NotNull(message = "encType不能为空")
private String encType = "aes";
@Pattern(regexp = "md5|sha", message = "签名算法格式错误")
private String signType = "md5";
private String signData;
@NotEmpty(message = "busiName不能为空")
private String busiName;
private String busiData;
private String timeStamp;
private String nonce;
private String clientId = "holic_01";
@NotNull
@Valid
private Tag tag;
@Email
private String email;
}
在要校验的实体对象的属性上添加相应的注解即可完成对该属性的校验。一般就是非空校验,格式校验,所用的注解也不多。@Pattern注解可以对被校验的属性进行正则匹配,不匹配的则校验失败,通常用于手机号、身份证号的校验。@Email是专门校验邮箱的注解。javax.validation.constraints包下有全部的注解,可以自行查看用法。一旦有参数不符合注解的要求,比如非空字段为null了,那么@NotNull注解中的message就会被保存到Controller中的result中,hasErrors()方法就会返回true。 这里需要说明一点,如果是要校验对象参数里的属性,比如上例中的tag,需要额外增加@Valid注解,表明递归校验。
还有一种方式,不在Controller层使用@Valid注解,也就是校验的时机不在Controller层了:
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<CommonReq>> validate = validator.validate(req);
代码大概就这个鬼样子。Validation类也是在javax.validation包下。校验可以在任何位置进行,只要把要校验的对象扔到validator的validate()方法中即可。如果validate .size() > 0为true,那么就说明有参数校验未通过,ConstraintViolation<T>这个类有许多属性,可以根据自己的需要自行获取。