素材巴巴 > 程序开发 >

必须拿下的Springboot参数校验

程序开发 2023-09-12 14:42:28

实际项目中不仅仅前端需要做必填项等校验,为防止非法参数对业务造成影响,后端也需要对相关参数做校验,接下来就学习一下在Springboot项目中如何对参数进行校验。本文Springboot版本为2.6.8

引入依赖

如果Springboot版本小于2.3.xspring-boot-starter-web会自动传入hibernate-validator依赖。如果Springboot版本大于2.3.x,则需要手动引入依赖: 温馨提示:7.x.x版本可能会不起效


 org.hibernatehibernate-validator6.2.0.Final
 
 

或者直接引入springboot的场景启动器

        org.springframework.bootspring-boot-starter-validation2.7.0

@Validated和@Valid区别

@Validated@Valid进行了二次封装,但是二者有以下的区别:

统一异常处理

如果校验不通过会报MethodArgumentNotValidException或者 ConstraintViolationException

@RestControllerAdvice
 public class ParamException {@ExceptionHandler({MethodArgumentNotValidException.class})@ResponseStatus(HttpStatus.BAD_REQUEST)public ResultReturn handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {BindingResult bindingResult = ex.getBindingResult();StringBuilder sb = new StringBuilder("校验失败:");for (FieldError fieldError : bindingResult.getFieldErrors()) {sb.append(fieldError.getField()).append(":").append(fieldError.getDefaultMessage()).append(", ");}String msg = sb.toString();return ResultReturnUtil.fail(ErrorCodeEnum.PARAM_ERROR.getCode(),msg);}@ExceptionHandler({ConstraintViolationException.class})@ResponseStatus(HttpStatus.BAD_REQUEST)public ResultReturn handleConstraintViolationException(ConstraintViolationException ex) {return ResultReturnUtil.fail(ErrorCodeEnum.PARAM_ERROR.getCode(),ex.getMessage());}
 }

我们可以把要返回的错误信息定义在枚举中

@Getter
 @ToString
 public enum ErrorCodeEnum {PARAM_ERROR(10001,"参数错误");private Integer code;private String msg;ErrorCodeEnum(Integer code, String msg) {this.code = code;this.msg = msg;}
 }

再来个统一返回格式

@Data
 public class ResultReturn implements Serializable {private static final long serialVersionUID = 5805792987639183304L;private Integer code;private String msg;private Object data;public ResultReturn(){super();}public ResultReturn(Integer code, String msg){this.code = code;this.msg = msg;}public ResultReturn(Integer code, String msg, Object data){this.code = code;this.msg = msg;this.data = data;}
 }
public class ResultReturnUtil {/*** 成功 返回默认码值* @param msg* @return*/public static ResultReturn success(String msg){return new ResultReturn(0,msg);}/*** 成功  返回自定义码值* @param code* @param msg* @return*/public static ResultReturn success(Integer code, String msg){return new ResultReturn(code,msg);}public static ResultReturn success(String msg, Object data){return  new ResultReturn(0,msg,data);}public static ResultReturn fail(String msg){return new ResultReturn(-1,msg);}public static ResultReturn fail(Integer code, String msg){return new ResultReturn(code,msg);}
 }
 

RequestBody参数校验

当我们使用POST、PUT请求时会使用 @RequestBody+实体类 来接收参数。此时只需要给实体类加上@Validated注解就能实现自动参数校验。

@RestController
 public class TestController {@PostMapping("/addUser")public Boolean addUser(@RequestBody @Validated User user){//忽略service处理相关业务return true;}
 }

那么具体到每个参数的校验则需要在实体类中处理。

@Data
 public class User {private Long id;@NotBlank(message = "用户账号不能为空")@Length(min = 4, max = 10,message = "账号长度为4-10位")private String userName;@NotBlank(message = "密码不能为空")@Length(min = 6,max = 12,message = "密码长度为6-12位")private String password;@NotNull(message = "邮箱不能为空")@Email(message = "邮箱格式错误")private String email;/*** 性别 1为男生  2为女生*/@Min(value = 1,message = "最小值为1")@Max(value = 2,message = "最大值为2")private Integer sex;}
 

先请求一次试试

 requestParam/PathVariable参数校验

这种方式下参数都较少,必须在Controller类上标注@Validated注解,并在入参上声明约束注解

 接下来请求试一下

 特殊情况

也是上文提到的,pojo参数中有对象属性,那么要对这个对象中的属性校验该怎么做?

 比如我这里有个学生类

@Data
 public class Student {@NotBlank(message = "用户名不能为空")private String name;@Min(value = 10, message = "年龄不能小于10岁")private Integer age;@Email(message = "邮箱格式错误")private String email;@NotBlank(message = "班级名不能为空")private String className;@NotEmpty(message = "任课老师不能为空")@Size(min = 1, message = "至少有一个老师")private List teachers;
 }
@Data
 public class Teacher {@NotBlank(message = "老师姓名不能为空")private String teacherName;@Min(value = 1, message = "学科类型从1开始计算")private Integer type;
 }

测试一下

 很明显这个type的值并不符合要求, 需要在学生类的教师属性上加上@Valid注解

 参数校验注解大全

注解作用类型解释

null是否

能通过验证

@AssertFalseBoolean、boolean该字段值为false时,验证才能通过YES@AssertTrueBoolean、boolean该字段值为true时,验证才能通过YES@DecimalMax 数字类型(原子和包装)验证小数的最大值
@DecimalMax(value = "12.35")
 private double money;

YES@DecimalMin数字类型(原子和包装)验证小数的最小值YES@Digits数字类型(原子和包装)验证数字的整数位和小数位的位数是否超过指定的长度
@Digits(integer = 2, fraction = 2)
 private double money;

YES@EmailString该字段为Email格式,才能通过YES@Future时期、时间验证日期是否在当前时间之后,否则无法通过校验
@Future
 private Date date;

YES@FutureOrPresent时期、时间时间在当前时间之后 或者等于此时YES@Max数字类型(原子和包装)
//该字段的最大值为18,否则无法通过验证
 @Max(value = 18)
 private Integer age;

YES@Min数字类型(原子和包装)同上,不能低于某个值否则无法通过验证YES@Negative数字<0YES@NegativeOrZero数字=<0YES@NotBlankString 该注解用来判断字符串或者字符,只用在String上面

字符串不能为null,字符串trim()后也不能等于“”

NO@NotEmptyString、集合、数组、Map、链表List

不能为null,不能是空字符,集合、数组、map等size()不能为0;字符串trim()后可以等于“”

NO@NotNull任何类型使用该注解的字段的值不能为null,否则验证无法通过NO@Null修饰的字段在验证时必须是null,否则验证无法通过YES@Past时间、日期验证日期是否在当前时间之前,否则无法通过校验,必须是一个过去的时间或日期YES@PastOrPresent时间、日期验证日期是否在当前时间之前或等于当前时间YES@Pattern用于验证字段是否与给定的正则相匹配
@Pattern(regexp = "正则")
 private String name;

YES@Positive数字>0YES@PositiveOrZero数字>=0YES@Size字符串String、集合Set、数组Array、Map,List
修饰的字段长度不能超过5或者低于1
 @Size(min = 1, max = 5)
 private String name;

集合、数组、map等的size()值必须在指定范围内

    //只能一个@Size(min = 1, max = 1)private List names;

 YES


标签:

上一篇: Eclipse下导入gradle项目配置 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。