SpringBoot整合Hibernate-invalidate(JSR303校验)

SpringBoot整合Hibernate-invalidate(JSR303校验)

1、简介

Hibernate-invalidate的作用简单来说就是:做参数的验证,验证前端传入的参数是否合法

Hibernate-invalidator这个框架跟 Hibernate并没有什么关系、是一个独立的框架

SpringBoot默认使用该验证规则,不需要额外导入依赖

2、对象参数的校验

2.1、定义对象

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private Integer id;

    @NotNull(message = "用户名不能为空")
    @Length(min = 6, max = 10, message = "用户名长度只能是 6~10 位")
    private String name;

    @NotNull(message = "密码不能为空")
    @Length(min = 6, max = 10, message = "密码只能是 6~10 位")
    private String password;

    @NotNull(message = "年龄不能为空")
//    @Pattern(regexp = "\\d", message = "只能是数字")
    @Range(min = 16, max = 40, message = "年龄必须在16~40之间")
    private Integer age;
}

2.2、定义controller

@RestController
public class UserController {

    private Logger logger = LoggerFactory.getLogger(UserController.class);

    @GetMapping("test1")
    public String test1(@Valid User user, BindingResult bindingResult) {
        // 判断校验是否出错,如果有错则返回true
        if (bindingResult.hasErrors()) {
            // 获取所有的校验错误的信息
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            for (FieldError fieldError : fieldErrors) {
                String field = fieldError.getField();   // 错误的字段名
                String message = fieldError.getDefaultMessage(); // 错误的详细信息
                logger.info("错误的字段名:" + field + "  ;错误的信息为:" + message);
            }
        }
        return "测试validator验证规则:@Valid-对象参数-user: " + user;
    }

    @GetMapping("test2")
    public String test2(@Validated(Register.class) User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            for (FieldError fieldError : fieldErrors) {
                String field = fieldError.getField();
                String message = fieldError.getDefaultMessage();
                logger.info("错误的字段名:" + field + "  ;错误的信息为:" + message);
            }
        }
        return "测试validator验证规则:@Validated(Register.class)-对象参数-user: " + user;
    }

    @GetMapping("test3")
    public String test3(@Validated(Login.class) User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            for (FieldError fieldError : fieldErrors) {
                String field = fieldError.getField();
                String message = fieldError.getDefaultMessage();
                logger.info("错误的字段名:" + field + "  ;错误的信息为:" + message);
            }
        }
        return "测试validator验证规则:@Validated(Login.class)-对象参数-user: " + user;
    }
}

3、方法参数的校验

3.1、写配置文件支持单个参数的校验

 	/**
     * 开启Hiberante-invalidator对方法单个参数校验的支持
     * @return
     */
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor(){
        return new MethodValidationPostProcessor();
    }

3.2、在校验的类上添加如下的注解

@Validated  	

3.3、编写要校验的方法

@RestController
@Validated
public class ParamController {

    Logger logger = LoggerFactory.getLogger(ParamController.class);

    @GetMapping("param1")
    public String param1(@NotNull(message = "账号不能为空") @Length(min = 3, max = 6, message = "账号只能是3~6位") String account,
                         @NotNull(message = "密码不能为空") @Length(min = 6, max = 10, message = "账号只能是6~10位") String password) {
        
        return "测试:验证方法参数:普通参数;account: " + account + "  password: " + password;
    }
}

3.4、全局异常处理器

  • 此方法不能直接返回异常结果,只能自己处理异常,需要配合自定义全局异常处理器处理

  • 全局异常处理器

    /**
     * 配置全局异常解析器
     */
    @ControllerAdvice
    public class CommonExceptionHandler {
    
        /**
         * 处理 JSR303 校验不通过异常
         */
        @ExceptionHandler(ConstraintViolationException.class)
        @ResponseBody
        public String constraintViolationException(ConstraintViolationException exception) {
            // 验证不通过的信息
            Iterator<ConstraintViolation<?>> iterator = exception.getConstraintViolations().iterator();
            StringBuilder str = new StringBuilder();
            while(iterator.hasNext()){
                str.append(iterator.next().getMessage());
                str.append("\n");
            }
            return "参数校验失败,错误信息为:" + str.toString();
        }
    }
    
  • 校验失败的异常均为:ConstraintViolationException

4、Hibernate-invalidator的校验模式

4.1、普通模式的校验

就是所有的字段都要校验、而且校验不通过的 都要返回这个校验错误的信息

4.2、快速校验模式

只要校验中一个没通过、后面的就不用校验了

下面就是配置校验模式

配置文件中

 	/**
     * 配置校验的规则 是普通校验还是快速校验
     *      此项一般不配,使用默认值普通校验
     */
    @Bean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                .configure()
                .addProperty("Hibernate.validator.fail_fast", "false") // true 快速校验模式;false(默认值) 普通校验模式
                // .failFast( true )    和上一行等价
                .buildValidatorFactory();
        return validatorFactory.getValidator();
    }

5、分组校验

5.1、创建分组(空接口即可)

public interface Login {
}

public interface Register {
}

5.2、在方法上表明当前这个方法属于哪一个组

	@GetMapping("test2")
    public String test2(@Validated(Register.class) User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            for (FieldError fieldError : fieldErrors) {
                String field = fieldError.getField();
                String message = fieldError.getDefaultMessage();
                logger.info("错误的字段名:" + field + "  ;错误的信息为:" + message);
            }
        }
        return "测试validator验证规则:@Validated(Register.class)-对象参数-user: " + user;
    }

    @GetMapping("test3")
    public String test3(@Validated(Login.class) User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            for (FieldError fieldError : fieldErrors) {
                String field = fieldError.getField();
                String message = fieldError.getDefaultMessage();
                logger.info("错误的字段名:" + field + "  ;错误的信息为:" + message);
            }
        }
        return "测试validator验证规则:@Validated(Login.class)-对象参数-user: " + user;
    }

5.3、在对象上标明当前属性需要在哪些分组做校验

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private Integer id;

    @NotNull(message = "用户名不能为空")
    @Length(min = 6, max = 10, message = "用户名长度只能是 6~10 位", groups = {Register.class, Login.class})
    private String name;

    @NotNull(message = "密码不能为空")
    @Length(min = 6, max = 10, message = "密码只能是 6~10 位", groups = {Register.class, Login.class})
    private String password;

    @NotNull(message = "年龄不能为空", groups = {Register.class})
//    @Pattern(regexp = "\\d", message = "只能是数字", groups = {Register.class})
    @Range(min = 16, max = 40, message = "年龄必须在16~40之间", groups = {Register.class})
    private Integer age;
}

6、常见的注解

@Null 元素必须为null
@NotNull 元素不能为null
@AssertTrue 元素的值必须为true
@Assertfalse 元素必须为false
@Min | @DecimalMin :元素的值必须是一个数字  这个数字 的值必须大于等于最小值
@Max | @DecimalMax : 元素的值必须是一个数字  这个数字 的值必须小于等于最大值
@Size :表示的是元素的大小在指定的范围内
@Past :表示的是元素的值 必须是一个过期的时间
@Future:表示的是元素的值 必须在一个将来的时间
@Pattern(rex=xxx) :正则表达式判断的
@Notblack 字符串非null 长度必须大于0
@Email :邮箱判断
@length :长度判断
@NotEmpty :字符串非空
@Range :表示的是元素必须在指定的范围内

发布了21 篇原创文章 · 获赞 5 · 访问量 2055

猜你喜欢

转载自blog.csdn.net/fan521dan/article/details/104486946
今日推荐