@Valid
@Valid用于限制请求的对象里的参数是否必传,适用于只是接口之间调用的情况
在Cotronller层上加@Valid注解:
@RequestMapping("/do_login")
@ResponseBody
public Result<Boolean> doLogin(HttpServletResponse response,@Valid LoginVo loginVo){//valid参数校验会抛出bindexception
log.info(loginVo.toString());
//userService.login(loginVo);
return Result.success(true);
}
注解的实体类:
public class LoginVo {
@NotNull(message="手机号未填")
@IsMobile(message="非手机号")
private String mobile;
@NotNull(message="密码未填")
@Length(min=32,message="密码长度太短")//md5处理过有32位
private String password;
public String getmobile() {
return mobile;
}
public void setmobile(String mobile) {
this.mobile = mobile;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "LoginVo [mobile=" + mobile + ", password=" + password + "]";
}
}
编辑全局异常捕捉类
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
private static Logger log=LoggerFactory.getLogger(LoginController.class);
@ExceptionHandler(value = Exception.class)
public Result<String> exceptionHandler(HttpServletRequest request, Exception e) {
if (e instanceof BindException) {
log.info("绑定异常");
BindException ex = (BindException) e;
List<ObjectError> errors = ex.getAllErrors();
ObjectError error = errors.get(0);
String msg = error.getDefaultMessage();
log.info("Bind"+msg);
return Result.error(CodeMsg.BIND_ERROR.fillArgs(msg));
} else if(e instanceof GlobalException){
log.info("全局异常");
GlobalException ex=(GlobalException)e;
return Result.error(ex.getCm());
}
else {
return Result.error(CodeMsg.SERVER_ERROR);
}
}
}
@Valid相关注解类型(JSR-303)
注解 | 作用 |
---|---|
@Null | 限制只能为null |
@NotNull | 限制必须不为null |
@AssertFalse | 限制必须为false |
@AssertTrue | 限制必须为true |
@DecimalMax(value) | 限制必须为一个不大于指定值的数字 |
@DecimalMin(value) | 限制必须为一个不小于指定值的数字 |
@Digits(integer,fraction) | 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction |
@Future | 限制必须是一个将来的日期 |
@Max(value) | 限制必须为一个不大于指定值的数字 |
@Min(value) | 限制必须为一个不小于指定值的数字 |
@Past | 限制必须是一个过去的日期 |
@Pattern(value) | 限制必须符合指定的正则表达式 |
@Size(max,min) | 限制字符长度必须在min到max之间 |
@Past | 验证注解的元素值(日期类型)比当前时间早 |
@NotEmpty | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
@NotBlank | 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格 |
验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式 | |
@Length(min=, max=) | 验证元素值长度是否在指定长度范围内 |
@Valid注解-自定义(JSR-303自定义验证)
以 @IsMobile为例
首先创建一个同名接口:
@Documented
@Constraint(validatedBy = {IsMobileValidator.class}) //引入实现类
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) //@Target注解标记另外的注解用于限制此注解可以应用哪种Java元素类型。
@Retention(RUNTIME)
public @interface IsMobile {
//true:参数必须有,进行格式校验 false:参数可以为空,不为空时也要进行进行格式校验
boolean required() default true;
//未通过注解后输出的信息,可以自定义
String message() default "手机号码格式错误";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
注解实现类,必须实现ConstraintValidator:
public class IsMobileValidator implements ConstraintValidator<IsMobile, String> {
private static Logger log=LoggerFactory.getLogger(LoginController.class);
public static boolean required=false;
public void initialize(IsMobile constraintAnnotation) {
required = constraintAnnotation.required();
}
@Override
public boolean isValid(String mobile, ConstraintValidatorContext arg1) {
if(required){ //是否必须传参
log.info("检查手机号异常");
return ValidatorUtil.isMobile(mobile);
}else{
if(StringUtils.isEmpty(mobile)){
log.info("检查手机号异常");
return true;
}else{
log.info("检查手机号异常");
return ValidatorUtil.isMobile(mobile);//判断是否为手机号
}
}
}