Springboot统一参数验证方式

Springboot统一验证方式

在提供http api 接口形式的服务中,通过都会传递参数为一个对象。我们需要对这个对象的各个字段进行校验。来判断是否为合法值。

 

传统的方式为自己获取每个字段的值,自己写方法进行判断。

这种方式太过麻烦。

 

推荐使用

推荐使用 validation  通过其JSR303 Java 规范提案 的验证方法来进行验证。进行简化。

 

 

@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   验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

 

如不满足还可以自定义验证注解。

 

 

使用方式:

 

public class user

{

    @NotNull(message = "姓名不可为空")

    private String name;

    @DecimalMin(value = "100",message = "年龄必须大于100")

    private Integer age;

}

 

public user create(@RequestBody @Valid user u) {}

 

 

这里有个问题,@Valid 如果有验证不通过的约束。将会抛出一个异常,这个异常将直接响应。

 

响应json结构:

       {

    "timestamp": 1554169655057,

    "status": 400,

    "error": "Bad Request",

    "exception": "org.springframework.web.bind.MethodArgumentNotValidException",

    "errors": [

        {

            "codes": [

                "NotNull.user.name",

                "NotNull.name",

                "NotNull.java.lang.String",

                "NotNull"

            ],

            "arguments": [

                {

                    "codes": [

                        "user.name",

                        "name"

                    ],

                    "arguments": null,

                    "defaultMessage": "name",

                    "code": "name"

                }

            ],

            "defaultMessage": "姓名不可为空",

            "objectName": "user",

            "field": "name",

            "rejectedValue": null,

            "bindingFailure": false,

            "code": "NotNull"

        }

    ],

    "message": "Validation failed for object='user'. Error count: 1",

    "path": "/a"

}

 

这种方式在http api 的情况下非常不优化。

 

验证异常统一处理拦截器

 

我们可以提供自定义异常拦截器来实现对这个异常的补货,返回统一约定的响应结构体。

 

 

@ControllerAdvice

public class ExceptionControllerAdvice

{

    /**

     * 对验证约束异常进行拦截,返回约定的响应体

     */

    @ExceptionHandler(MethodArgumentNotValidException.class)

    @ResponseBody

    public ResponseEntity bindExceptionHandler(MethodArgumentNotValidException ex)   {

        BindingResult bindingResult = ex.getBindingResult();

        List<ObjectError> errors = bindingResult.getAllErrors();

        StringBuffer buffer = new StringBuffer();

        for (ObjectError error : errors) {

            buffer.append(error.getDefaultMessage()).append(" ");

        }

        return new ResponseEntity("403", buffer.toString());

    }

 

    /**

     * 参数类型转换错误

     */

    @ExceptionHandler(HttpMessageConversionException.class)

    @ResponseBody

    public ResponseEntity parameterTypeException(HttpMessageConversionException exception) {

        return new ResponseEntity("403", exception.getCause().getLocalizedMessage());

    }

}

 

 

这样我们就可以简化对请求参数的校验了。

posted @ 2019-04-02 15:22  atliwen  阅读(5954)  评论(0编辑  收藏  举报