• 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());

        }

    }

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

  • 相关阅读:
    设计模式的七大原则(Java)
    多线程学习
    力扣题解-1385.两个数组间的距离值
    java集合框架俯瞰
    类加载和双亲委派机制
    关于String
    Object类源码注释
    pom文件标签-仅做手册使用
    effective Java 系列笔记1
    postgres in查询优化
  • 原文地址:https://www.cnblogs.com/atliwen/p/10642836.html
Copyright © 2020-2023  润新知