JSR-303规范对请求参数校验,以及异常统一处理,内嵌对象的属性校验

1.引入依赖,版本需要对应:其中javax.validation是定义规范的一些接口,而实现由hibernate-validator实现

      <dependency>
           <groupId>javax.validation</groupId>
           <artifactId>validation-api</artifactId>
           <version>2.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.7.Final</version>
        </dependency>

2.创建一个请求对象:

public class OrderRequest {

    private Long id;
    @NotBlank(message ="名称不能为空" )
    private String name;
    @Pattern(regexp = "http://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?",message = "url路径不对")
    private String url;
    @Email(regexp="/+d/",message = "邮件格式不对")
    private String email;
    @DecimalMax("20")
    @DecimalMin("10")
    private BigDecimal amount;
}

3.contoller实现:

   @RequestMapping("/order")
    @ResponseBody
    public Map<String, String> testValid(@Valid @RequestBody OrderRequest orderRequest, BindingResult bindingResult){
        boolean hasFieldErrors = bindingResult.hasFieldErrors();
        Map<String, String> map = new HashMap<>();

        if(hasFieldErrors){
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                String field = fieldError.getField();
                String defaultMessage = fieldError.getDefaultMessage();
                map.put(field,defaultMessage);
            }
            map.put("errorCode","400");
            return map;
        }
        map.put("errorCode","200");
        return map;
    }

 

4.postman调用:

 

 问题1:当所给的注解都满足不了需求的时候,如何自定义注解:需求:校验姓名是否带有gogo,参考注解:

 

 

 参考上面NotBlank注解,定义一个Checkgogo注解:

@Documented
@Constraint(validatedBy = { })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface CheckGogo {
    String message() default "{com.yang.xiao.hui.thymeleaf.controller.CheckGogo.message}";

    Class<?>[] groups() default { };

    Class<? extends Payload>[] payload() default { };
    String value();
}

我们需要定义一个使得该注解生效的类,点击@Constraint注解,看看需要一个怎么样的类:

 

 

 

 实现如下:

public class MyGogoConstraintValidator implements ConstraintValidator<CheckGogo,String> {

    private String needIncludeValue;
    @Override
    public void initialize(CheckGogo constraintAnnotation) {
        needIncludeValue = constraintAnnotation.value(); //参数需要包含的字符
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        
        return value.indexOf(needIncludeValue)!=-1 //校验参数是否包含该字符
    }
}

在注解上加上该实现类:

 

 配置默认信息:在resources文件夹下新增:ValidationMessages.properties

 

 测试:

 

 

 

postMan调用:

 

 自定义提示语:

 

 

 问题2:有些字段,我们在修改时希望不为空,在新增时希望为空,如编号,如何处理? 这里就要用到分组了,先定义2个空接口:

//新增分组
public interface AddCheck {

} 

//修改分组
public interface UpdateCheck {
}

在校验字段时加上分组字段:

 

 修改controller:

 

 

 测试:

 问题3:上面所讲,校验失败后,每个controller都要自己处理校验失败的异常,如何统一校验:

定义一个异常处理类:

    

@RestControllerAdvice(basePackages="com.yang.xiao.hui.thymeleaf.controller")
public class CommonExceptionProcessController {

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Map errorHandler(MethodArgumentNotValidException ex) { //处理参数校验异常
        Map map = new HashMap();
        BindingResult bindingResult = ex.getBindingResult();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            map.put(fieldError.getField(), fieldError.getDefaultMessage());
        }

        map.put("code", 400);

        return map;
    }

    @ExceptionHandler(value = Throwable.class)
    public Map errorHandler(Throwable ex) {
        Map map = new HashMap();
        map.put("code", 500);
        map.put("message", "服务挂了");

        return map;
    }

}

修改controller:

 @RequestMapping("/order")
    @ResponseBody
    public BigDecimal testValid(@Validated(UpdateCheck.class) @RequestBody OrderRequest orderRequest){ //这里不用再单独处理bindResult了,只管业务代码即可

        return   new BigDecimal("20");
    }

postMan调用:

 //嵌套对象如何校验:

 

 只要在内嵌对象添加一个@Valid注解即可

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

posted @ 2021-01-05 18:38  yangxiaohui227  阅读(385)  评论(0编辑  收藏  举报