精华内容
下载资源
问答
  • SpringBoot参数校验注解

    千次阅读 2020-07-10 17:01:50
    SpringBoot参数校验注解 使用自定义参数校验的优势 1.消除耦合,如果哪天你需要更改正则表达式你需要在每个引用的地方进行更改 2.通俗易懂,可以一目了然表示这是一个手机校验的注解,即便代码的阅读者对正则表达式...

    SpringBoot参数校验注解

    使用自定义参数校验的优势

    1.消除耦合,如果哪天你需要更改正则表达式你需要在每个引用的地方进行更改

    2.通俗易懂,可以一目了然表示这是一个手机校验的注解,即便代码的阅读者对正则表达式不太熟悉,也可以猜出这个注解用来干嘛的

    3.更强大,自定义校验逻辑,可以干更多的事情,甚至可以在校验器中引入其他的组件如使用@Autowired引入服务类进行处理校验判断

    maven配置

    spring-boot-starter-web包自动依赖hibernate-validator,不用再重复引入

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.3.1.Final</version>
    </dependency>
    

    声明一个bean注册到spring容器,这个bean是一个容器后处理器,会把校验的逻辑通过AOP织入有@Validated注解的class,具体可以看这个类的源码

    这一步在springboot其实也不用做,ValidationAutoConfiguration这个配置类自动帮我们做了

     @Bean
        public MethodValidationPostProcessor methodValidationPostProcessor(){
         return new MethodValidationPostProcessor();
        }
    
    

    验证不通过会产生异常,因为我们项目提供rest接口,所以通过全局捕获异常,然后转换为json给前台

    
    @ControllerAdvice
    public class GlobalExceptionHandler {
    
        /**
         * 用来处理bean validation异常
         * @param ex
         * @return
         */
        @ExceptionHandler(ConstraintViolationException.class)
        @ResponseBody
        public  WebResult resolveConstraintViolationException(ConstraintViolationException ex){
            WebResult errorWebResult = new WebResult(WebResult.FAILED);
            Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
            if(!CollectionUtils.isEmpty(constraintViolations)){
                StringBuilder msgBuilder = new StringBuilder();
                for(ConstraintViolation constraintViolation :constraintViolations){
                    msgBuilder.append(constraintViolation.getMessage()).append(",");
                }
                String errorMessage = msgBuilder.toString();
                if(errorMessage.length()>1){
                    errorMessage = errorMessage.substring(0,errorMessage.length()-1);
                }
                errorWebResult.setInfo(errorMessage);
                return errorWebResult;
            }
            errorWebResult.setInfo(ex.getMessage());
            return errorWebResult;
        }
    
        @ExceptionHandler(MethodArgumentNotValidException.class)
        @ResponseBody
        public WebResult resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex){
            WebResult errorWebResult = new WebResult(WebResult.FAILED);
            List<ObjectError>  objectErrors = ex.getBindingResult().getAllErrors();
            if(!CollectionUtils.isEmpty(objectErrors)) {
                StringBuilder msgBuilder = new StringBuilder();
                for (ObjectError objectError : objectErrors) {
                    msgBuilder.append(objectError.getDefaultMessage()).append(",");
                }
                String errorMessage = msgBuilder.toString();
                if (errorMessage.length() > 1) {
                    errorMessage = errorMessage.substring(0, errorMessage.length() - 1);
                }
                errorWebResult.setInfo(errorMessage);
                return errorWebResult;
            }
            errorWebResult.setInfo(ex.getMessage());
            return errorWebResult;
        }
    }
    
    

    这两个异常分别对应校验的两种使用方式

    这两个异常分别对应校验的两种使用方式

    1. 在方法里面校验
    2. 在bean对象里面校验
      经过测试,以上两种形式的数据验证不仅仅对controller层有用,在service层也行,只要这个类在spring ioc容器里面

    常用的参数校验的注解

    注解描述
    @Valid对po实体尽心校验
    @AssertFalse所注解的元素必须是Boolean类型,且值为false
    @AssertTrue所注解的元素必须是Boolean类型,且值为true
    @DecimalMax所注解的元素必须是数字,且值小于等于给定的值
    @DecimalMin所注解的元素必须是数字,且值大于等于给定的值
    @Digits所注解的元素必须是数字,且值必须是指定的位数
    @Future所注解的元素必须是将来某个日期
    @Max所注解的元素必须是数字,且值小于等于给定的值
    @Min所注解的元素必须是数字,且值大于等于给定的值
    @Range所注解的元素需在指定范围区间内
    @NotNull所注解的元素值不能为null
    @NotBlank所注解的元素值有内容
    @Null所注解的元素值为null
    @Past所注解的元素必须是某个过去的日期
    @PastOrPresent所注解的元素必须是过去某个或现在日期
    @Pattern所注解的元素必须满足给定的正则表达式
    @Size所注解的元素必须是String、集合或数组,且长度大小需保证在给定范围之内
    @Email所注解的元素需满足Email格式

    使用方法

    在方法参数上使用

    @Controller
    @Validated
    public class ValidationController {
    
        @GetMapping("/validate1")
        @ResponseBody
        public String validate1(
                @Size(min = 1,max = 10,message = "姓名长度必须为1到10")@RequestParam("name") String name,
                @Min(value = 10,message = "年龄最小为10")@Max(value = 100,message = "年龄最大为100") @RequestParam("age") Integer age,
                @Future @RequestParam("birth")@DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss") Date birth){
            return "validate1";
        }
    }
    

    在bean内属性上使用

    public class User {

        @Size(min = 1,max = 10,message = "姓名长度必须为1到10")
        private String name;
    
        @NotEmpty
        private String firstName;
    
        @Min(value = 10,message = "年龄最小为10")@Max(value = 100,message = "年龄最大为100")
        private Integer age;
    
        @Future
        @JSONField(format="yyyy-MM-dd HH:mm:ss")
        private Date birth;
    
        ...getter setter
    }
    

    在controller对应User实体前增加@Valid注解

    @PostMapping("/validate2")
    @ResponseBody
    public User validate2(@Valid @RequestBody User user){
        return user;
    }
    

    message支持表达式和EL表达式 ,比如message = “姓名长度限制为{min}到{max} ${1+2}”)

    想把错误描述统一写到properties的话,在classpath下面新建ValidationMessages_zh_CN.properties文件(注意value需要转换为unicode编码),然后用{}格式的占位符

    扩展

    创建约束注解类

    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    @Constraint(validatedBy = { HandsomeBoyValidator.class})
    public @interface HandsomeBoy {
    
        String message() default "盛超杰最帅";
    
        String name();
    
        Class<?>[] groups() default { };
    
        Class<? extends Payload>[] payload() default {};
    }
    
    

    注意:message用于显示错误信息这个字段是必须的,groups和payload也是必须的
    @Constraint(validatedBy = { HandsomeBoyValidator.class})用来指定处理这个注解逻辑的类

    一开始写了这个自定义注解和验证类,发现没有生效,最后发现是@Constraint这个注解里的类没有配置,还跟了很多源码,蛋疼,总的来讲,这个配置还是挺方便的

    创建验证器类

    public class HandsomeBoyValidator implements ConstraintValidator<HandsomeBoy, User> {
    
        private String name;
    
        /**
         * 用于初始化注解上的值到这个validator
         * @param constraintAnnotation
         */
        @Override
        public void initialize(HandsomeBoy constraintAnnotation) {
            name =constraintAnnotation.name();
        }
    
        /**
         * 具体的校验逻辑
         * @param value
         * @param context
         * @return
         */
        @Override
        public boolean isValid(User value, ConstraintValidatorContext context) {
            return name ==null || name.equals(value.getName());
        }
    }
    
    

    这边的功能是user类里面的name字段必须和配置的一样,否则输出一个事实

    @PostMapping("/validate3")
    @ResponseBody
    public User validate3(@Valid @HandsomeBoy(name = "scj",message = "盛超杰第二帅") @RequestBody  User user){
        return user;
    }
    

    Hibernate validator官方文档

    demo源码下载

    https://github.com/shengchaojie/springboot-validation-demo

    本人有所修改,与原文有所差别。

    链接:https://www.jianshu.com/p/89a675b7c900
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • @Null 被注释的元素必须为 null @NotNull 被注释的元素必须不为 null @AssertTrue 被注释的元素必须为 true @AssertFalse 被注释的元素必须为 false @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定...

    https://blog.csdn.net/Goodbye_Youth/article/details/94876164

    展开全文
  • SpringBoot注解校验参数

    2020-01-07 10:09:35
    import com.fasterxml.jackson.annotation.JsonFormat... import io.swagger.annotations.ApiModel; import lombok.Data; import javax.validation.constraints.*; import java.io.Serializable;...import java.util.D...
    import com.fasterxml.jackson.annotation.JsonFormat;
    import io.swagger.annotations.ApiModel;
    import lombok.Data;
    
    import javax.validation.constraints.*;
    import java.io.Serializable;
    import java.util.Date;
    
    @Data
    @ApiModel(value = "用户")
    public class Member implements Serializable {
        @NotNull(message = "名称不能为空")    //被注释的元素必须不为 null
        @NotBlank(message = "名称不能为空")	//验证字符串非null,且长度必须大于0
        private String name;
    
        @Email(message = "邮箱格式错误")  //被注释的元素必须是电子邮箱地址
        private String email;
    
        //被注释的元素必须符合指定的正则表达式
        @Pattern(regexp = "^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$" , message = "手机号格式有误")
        @Max(value = 11, message = "手机号只能为{max}位") //被注释的元素必须是一个数字,其值必须小于等于指定的最大值
        @Min(value = 11, message = "手机号只能为{min}位") //被注释的元素必须是一个数字,其值必须大于等于指定的最小值
        private Long phone;
    
        @Null //被注释的元素必须为 null
        private String card;
    
        @AssertTrue    //被注释的元素必须为 true
        private Boolean putaway;
    
        @AssertFalse   //被注释的元素必须为 false
        private Boolean soldout;
    
        @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")
        @Past	  //被注释的元素必须是一个过去的日期
        @Future	  //被注释的元素必须是一个将来的日期
        private Date createTime;
        
    }

     

    展开全文
  • 一、PathVariable 校验 在定义 Restful 风格的接口时,通常会采用 PathVariable 指定关键业务参数,如下: @GetMapping("/path/{group:[a-zA-Z0-9_]+}/{userid}") @ResponseBody public String path(@...

    一、PathVariable 校验

    在定义 Restful 风格的接口时,通常会采用 PathVariable 指定关键业务参数,如下:

        @GetMapping("/path/{group:[a-zA-Z0-9_]+}/{userid}")
        @ResponseBody
        public String path(@PathVariable("group") String group, @PathVariable("userid") Integer userid) {
            return group + ":" + userid;
        }

    {group:[a-zA-Z0-9_]+} 这样的表达式指定了 group 必须是以大小写字母、数字或下划线组成的字符串。
    我们试着访问一个错误的路径:

        GET /path/testIllegal.get/10000

    此时会得到 404的响应,因此对于PathVariable 仅由正则表达式可达到校验的目的

    二、方法参数校验

    类似前面的例子,大多数情况下,我们都会直接将HTTP请求参数映射到方法参数上。

        @GetMapping("/param")
        @ResponseBody
        public String param(@RequestParam("group")@Email String group, 
                            @RequestParam("userid") Integer userid) {
           return group + ":" + userid;
        }

    上面的代码中,@RequestParam 声明了映射,此外我们还为 group 定义了一个规则(复合Email格式)
    这段代码是否能直接使用呢?答案是否定的,为了启用方法参数的校验能力,还需要完成以下步骤:

    • 声明 MethodValidationPostProcessor
        @Bean
        public MethodValidationPostProcessor methodValidationPostProcessor() {
             return new MethodValidationPostProcessor();
        }
    • Controller指定@Validated注解
        @Controller
        @RequestMapping("/validate")
        @Validated
        public class ValidateController {

    如此之后,方法上的@Email规则才能生效。

    校验异常
    如果此时我们尝试通过非法参数进行访问时,比如提供非Email格式的 group
    会得到以下错误:

        GET /validate/param?group=simple&userid=10000
        ====>
        {
            "timestamp": 1530955093583,
            "status": 500,
            "error": "Internal Server Error",
            "exception": "javax.validation.ConstraintViolationException",
            "message": "No message available",
            "path": "/validate/param"
        }

    而如果参数类型错误,比如提供非整数的 userid,会得到:

        GET /validate/param?group=simple&userid=1f
        ====>
        {
            "timestamp": 1530954430720,
            "status": 400,
            "error": "Bad Request",
            "exception": "org.springframework.web.method.annotation.MethodArgumentTypeMismatchException",
            "message": "Failed to convert value of type 'java.lang.String' to required type 'java.lang.Integer'; nested exception is java.lang.NumberFormatException: For input string: \"1f\"",
            "path": "/validate/param"
        }

    当存在参数缺失时,由于定义的@RequestParam注解中,属性 required=true,也将会导致失败:

        GET /validate/param?userid=10000
        ====>
        {
            "timestamp": 1530954345877,
            "status": 400,
            "error": "Bad Request",
            "exception": "org.springframework.web.bind.MissingServletRequestParameterException",
            "message": "Required String parameter 'group' is not present",
            "path": "/validate/param"
        }

    三、表单对象校验

    页面的表单通常比较复杂,此时可以将请求参数封装到表单对象中,
    并指定一系列对应的规则,参考JSR-303

        public static class FormRequest {
    
            @NotEmpty
            @Email
            private String email;
    
            @Pattern(regexp = "[a-zA-Z0-9_]{6,30}")
            private String name;
    
            @Min(5)
            @Max(199)
            private int age;

    上面定义的属性中:

    • email必须非空、符合Email格式规则;
    • name必须为大小写字母、数字及下划线组成,长度在6-30个;
    • age必须在5-199范围内

    Controller方法中的定义:

        @PostMapping("/form")
        @ResponseBody
        public FormRequest form(@Validated FormRequest form) {
            return form;
        }

    @Validated指定了参数对象需要执行一系列校验。

    校验异常
    此时我们尝试构造一些违反规则的输入,会得到以下的结果:

        {
            "timestamp": 1530955713166,
            "status": 400,
            "error": "Bad Request",
            "exception": "org.springframework.validation.BindException",
            "errors": [
                {
                    "codes": [
                        "Email.formRequest.email",
                        "Email.email",
                        "Email.java.lang.String",
                        "Email"
                    ],
                    "arguments": [
                        {
                            "codes": [
                                "formRequest.email",
                                "email"
                            ],
                            "arguments": null,
                            "defaultMessage": "email",
                            "code": "email"
                        },
                        [],
                        {
                            "arguments": null,
                            "codes": [
                                ".*"
                            ],
                            "defaultMessage": ".*"
                        }
                    ],
                    "defaultMessage": "不是一个合法的电子邮件地址",
                    "objectName": "formRequest",
                    "field": "email",
                    "rejectedValue": "tecom",
                    "bindingFailure": false,
                    "code": "Email"
                },
                {
                    "codes": [
                        "Pattern.formRequest.name",
                        "Pattern.name",
                        "Pattern.java.lang.String",
                        "Pattern"
                    ],
                    "arguments": [
                        {
                            "codes": [
                                "formRequest.name",
                                "name"
                            ],
                            "arguments": null,
                            "defaultMessage": "name",
                            "code": "name"
                        },
                        [],
                        {
                            "arguments": null,
                            "codes": [
                                "[a-zA-Z0-9_]{6,30}"
                            ],
                            "defaultMessage": "[a-zA-Z0-9_]{6,30}"
                        }
                    ],
                    "defaultMessage": "需要匹配正则表达式\"[a-zA-Z0-9_]{6,30}\"",
                    "objectName": "formRequest",
                    "field": "name",
                    "rejectedValue": "fefe",
                    "bindingFailure": false,
                    "code": "Pattern"
                },
                {
                    "codes": [
                        "Min.formRequest.age",
                        "Min.age",
                        "Min.int",
                        "Min"
                    ],
                    "arguments": [
                        {
                            "codes": [
                                "formRequest.age",
                                "age"
                            ],
                            "arguments": null,
                            "defaultMessage": "age",
                            "code": "age"
                        },
                        5
                    ],
                    "defaultMessage": "最小不能小于5",
                    "objectName": "formRequest",
                    "field": "age",
                    "rejectedValue": 2,
                    "bindingFailure": false,
                    "code": "Min"
                }
            ],
            "message": "Validation failed for object='formRequest'. Error count: 3",
            "path": "/validate/form"
        }

    如果是参数类型不匹配,会得到:

        {
            "timestamp": 1530955359265,
            "status": 400,
            "error": "Bad Request",
            "exception": "org.springframework.validation.BindException",
            "errors": [
                {
                    "codes": [
                        "typeMismatch.formRequest.age",
                        "typeMismatch.age",
                        "typeMismatch.int",
                        "typeMismatch"
                    ],
                    "arguments": [
                        {
                            "codes": [
                                "formRequest.age",
                                "age"
                            ],
                            "arguments": null,
                            "defaultMessage": "age",
                            "code": "age"
                        }
                    ],
                    "defaultMessage": "Failed to convert property value of type 'java.lang.String' 
        to required type 'int' for property 'age'; nested exception is java.lang.NumberFormatException: 
        For input string: \"\"",
                    "objectName": "formRequest",
                    "field": "age",
                    "rejectedValue": "",
                    "bindingFailure": true,
                    "code": "typeMismatch"
                }
            ],
            "message": "Validation failed for object='formRequest'. Error count: 1",
            "path": "/validate/form"
        }

    Form表单参数上,使用@Valid注解可达到同样目的,而关于两者的区别则是:

    @Valid 基于JSR303,即 Bean Validation 1.0,由Hibernate Validator实现;
    @Validated 基于JSR349,是Bean Validation 1.1,由Spring框架扩展实现;

    后者做了一些增强扩展,如支持分组校验,有兴趣可参考这里

    四、RequestBody 校验

    对于直接Json消息体输入,同样可以定义校验规则:

        @PostMapping("/json")
        @ResponseBody
        public JsonRequest json(@Validated @RequestBody JsonRequest request) {
    
            return request;
        }
    
        ...
        public static class JsonRequest {
    
            @NotEmpty
            @Email
            private String email;
    
            @Pattern(regexp = "[a-zA-Z0-9_]{6,30}")
            private String name;
    
            @Min(5)
            @Max(199)
            private int age;

    校验异常
    构造一个违反规则的Json请求体进行输入,会得到:

        {
            "timestamp": 1530956161314,
            "status": 400,
            "error": "Bad Request",
            "exception": "org.springframework.web.bind.MethodArgumentNotValidException",
            "errors": [
                {
                    "codes": [
                        "Min.jsonRequest.age",
                        "Min.age",
                        "Min.int",
                        "Min"
                    ],
                    "arguments": [
                        {
                            "codes": [
                                "jsonRequest.age",
                                "age"
                            ],
                            "arguments": null,
                            "defaultMessage": "age",
                            "code": "age"
                        },
                        5
                    ],
                    "defaultMessage": "最小不能小于5",
                    "objectName": "jsonRequest",
                    "field": "age",
                    "rejectedValue": 1,
                    "bindingFailure": false,
                    "code": "Min"
                }
            ],
            "message": "Validation failed for object='jsonRequest'. Error count: 1",
            "path": "/validate/json"
        }

    此时与FormBinding的情况不同,我们得到了一个MethodArgumentNotValidException异常。
    而如果发生参数类型不匹配,比如输入age=1f,会产生以下结果:

        {
            "timestamp": 1530956206264,
            "status": 400,
            "error": "Bad Request",
            "exception": "org.springframework.http.converter.HttpMessageNotReadableException",
            "message": "Could not read document: Can not deserialize value of type int from String \"ff\": not a valid Integer value\n at [Source: java.io.PushbackInputStream@68dc9800; line: 2, column: 8](through reference chain: org.zales.dmo.boot.controllers.ValidateController$JsonRequest[\"age\"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type int from String \"ff\": not a valid Integer value\n at [Source: java.io.PushbackInputStream@68dc9800; line: 2, column: 8](through reference chain: org.zales.dmo.boot.controllers.ValidateController$JsonRequest[\"age\"])",
            "path": "/validate/json"
        }

    这表明在JSON转换过程中已经失败!

    五、自定义校验规则

    框架内预置的校验规则可以满足大多数场景使用,
    但某些特殊情况下,你需要制作自己的校验规则,这需要用到ContraintValidator接口。

    我们以一个密码校验的场景作为示例,比如一个注册表单上,
    我们需要检查 密码输入 与 密码确认 是一致的。

    **首先定义 PasswordEquals 注解

        @Documented
        @Constraint(validatedBy = { PasswordEqualsValidator.class })
        @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.TYPE })
        @Retention(RetentionPolicy.RUNTIME)
        public @interface PasswordEquals {
    
            String message() default "Password is not the same";
    
            Class<?>[] groups() default {};
    
            Class<? extends Payload>[] payload() default {};
        }

    在表单上声明@PasswordEquals 注解

        @PasswordEquals
        public class RegisterForm {
    
            @NotEmpty
            @Length(min=5,max=30)
            private String username;
    
            @NotEmpty
            private String password;
    
            @NotEmpty
            private String passwordConfirm;

    针对@PasswordEquals实现校验逻辑

        public class PasswordEqualsValidator implements ConstraintValidator<PasswordEquals, RegisterForm> {
    
            @Override
            public void initialize(PasswordEquals anno) {
            }
    
            @Override
            public boolean isValid(RegisterForm form, ConstraintValidatorContext context) {
                String passwordConfirm = form.getPasswordConfirm();
                String password = form.getPassword();
    
                boolean match = passwordConfirm != null ? passwordConfirm.equals(password) : false;
                if (match) {
                    return true;
                }
    
                String messageTemplate = context.getDefaultConstraintMessageTemplate();
    
                // disable default violation rule
                context.disableDefaultConstraintViolation();
    
                // assign error on password Confirm field
                context.buildConstraintViolationWithTemplate(messageTemplate).addPropertyNode("passwordConfirm")
                        .addConstraintViolation();
                return false;
    
            }
        }

    如此,我们已经完成了自定义的校验工作。

    六、异常拦截器

    SpringBoot 框架中可通过 @ControllerAdvice 实现Controller方法的拦截操作。
    可以利用拦截能力实现一些公共的功能,比如权限检查、页面数据填充,以及全局的异常处理等等。

    在前面的篇幅中,我们提及了各种校验失败所产生的异常,整理如下表:

    异常类型描述
    ConstraintViolationException违反约束,javax扩展定义
    BindException绑定失败,如表单对象参数违反约束
    MethodArgumentNotValidException参数无效,如JSON请求参数违反约束
    MissingServletRequestParameterException参数缺失
    TypeMismatchException参数类型不匹配

    如果希望对这些异常实现统一的捕获,并返回自定义的消息,
    可以参考以下的代码片段:

        @ControllerAdvice
        public static class CustomExceptionHandler extends ResponseEntityExceptionHandler {
    
            @ExceptionHandler(value = { ConstraintViolationException.class })
            public ResponseEntity<String> handle(ConstraintViolationException e) {
                Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
                StringBuilder strBuilder = new StringBuilder();
                for (ConstraintViolation<?> violation : violations) {
                    strBuilder.append(violation.getInvalidValue() + " " + violation.getMessage() + "\n");
                }
                String result = strBuilder.toString();
                return new ResponseEntity<String>("ConstraintViolation:" + result, HttpStatus.BAD_REQUEST);
            }
    
            @Override
            protected ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, HttpStatus status,
                    WebRequest request) {
                return new ResponseEntity<Object>("BindException:" + buildMessages(ex.getBindingResult()),
                        HttpStatus.BAD_REQUEST);
            }
    
            @Override
            protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
                    HttpHeaders headers, HttpStatus status, WebRequest request) {
                return new ResponseEntity<Object>("MethodArgumentNotValid:" + buildMessages(ex.getBindingResult()),
                        HttpStatus.BAD_REQUEST);
            }
    
            @Override
            public ResponseEntity<Object> handleMissingServletRequestParameter(MissingServletRequestParameterException ex,
                    HttpHeaders headers, HttpStatus status, WebRequest request) {
                return new ResponseEntity<Object>("ParamMissing:" + ex.getMessage(), HttpStatus.BAD_REQUEST);
            }
    
            @Override
            protected ResponseEntity<Object> handleTypeMismatch(TypeMismatchException ex, HttpHeaders headers,
                    HttpStatus status, WebRequest request) {
                return new ResponseEntity<Object>("TypeMissMatch:" + ex.getMessage(), HttpStatus.BAD_REQUEST);
            }
    
            private String buildMessages(BindingResult result) {
                StringBuilder resultBuilder = new StringBuilder();
    
                List<ObjectError> errors = result.getAllErrors();
                if (errors != null && errors.size() > 0) {
                    for (ObjectError error : errors) {
                        if (error instanceof FieldError) {
                            FieldError fieldError = (FieldError) error;
                            String fieldName = fieldError.getField();
                            String fieldErrMsg = fieldError.getDefaultMessage();
                            resultBuilder.append(fieldName).append(" ").append(fieldErrMsg).append(";");
                        }
                    }
                }
                return resultBuilder.toString();
            }
        }

    默认情况下,对于非法的参数输入,框架会产生 HTTP_BAD_REQUEST(status=400) 错误码,
    并输出友好的提示消息,这对于一般情况来说已经足够。

    更多的输入校验及提示功能应该通过客户端去完成(服务端仅做同步检查),
    客户端校验的用户体验更好,而这也符合富客户端(rich client)的发展趋势。

    展开全文
  • 常用参数校验注解: @AssertFalse 所注解的元素必须是Boolean类型,且值为false @AssertTrue 所注解的元素必须是Boolean类型,且值为true @DecimalMax 所注解的元素必须是数字,且值小于等于给定的值 @DecimalMin ...
  • 引包问题: 高版本中已经不再使用 javax.validation validation-api 1.1.0.Final 引入: org.springframework.boot spring-boot-starter-validation 封装的参数上加上相关检验注解 @Data public class QueryVO ...
  • 在实际项目中有些参数的校验SpringBoot提供的校验注解不足以满足我们的需求,这时候就需要自己写检验注解。 这里我们以检验接口请求中两个时间参数为例子,假定有一个接口 @PostMapping(value="/test") String ...
  • SpringBoot参数校验--List类型

    万次阅读 2018-11-16 11:49:52
    我们在写后台接口的时候,通常会定义DTO来接收参数,在DTO中使用注解书写验证的规则;然后在Controller层使用@validated注解来验证自己制定的校验规则。但当我们的接口接收的参数为List&lt;E&gt;时,可以...
  • 1、自定义注解并实现ConstraintValidator接口进行参数校验 首先自定义一个注解,用来标识需要校验的请求参数字段 @Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @...
  • springboot中进行参数校验注解是@validation,要想使用该注解,需要在pom.xml文件中导入依赖包: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-...
  • SpringBoot使用@Valid注解校验参数无效

    千次阅读 2020-09-18 16:55:32
    SpringBoot项目结合Validator进行参数校验,发现使用@Valid注解无效。 @Valid和@RequestBody 百度之后,有的说是注解@Valid和@RequestBody一起使用时候,@Valid注解必须在@RequestBody注解之前使用。如下: ...
  • 在gradle.build中加入 implementation(‘org.springframework.boot:spring-boot-starter-validation’)
  • SpringBoot的使用过程中,默认使用hibernate-validator作为参数校验的框架,但某些业务场景或校验比较复杂,通过默认提供的注解已经无法满足。此时,除了使用正则表达式来进行校验也可以使用自定义的注解。 比如,...
  • 在此之前写过一篇[SpringBoot统一参数校验](https://juejin.im/post/6844904081660575752)主要介绍了一些简单的校验方法。而这篇则是介绍一些进阶的校验方式。比如说:在某个接口编写的过程中肯定会遇到,当xxType值...
  • 文章目录1. 基础简介2. 框架简介2.1. validation-api2.2. jakarta.validation-api2.3. hibernate-validator2.4. spring-boot-starter-validation3. 注解说明3.1. 标识注解3.2....本文需要结合SpringBoot
  • 主要介绍了springboot~@Valid注解对嵌套类型的校验,主要介绍 @Valid在项目中的使用,需要的朋友可以参考下
  • 有关参数校验的使用可详见《springboot参数校验(validation)使用》 如何自定义一个validation注解? 自己定义validation注解需要使用@Constraint。@Constraint注解中是这样进行描述的: ...
  • SpringBoot参数校验/参数验证

    万次阅读 多人点赞 2019-05-08 13:47:56
    在控制器类的方法里自己写校验逻辑代码当然也可以,只是代码比较丑陋,有点“low”。业界有更好的处理方法,分别阐述如下。 2、PathVariable校验 @GetMapping("/path/{group:[a-zA-Z0-9_]+}/{userid}") @...
  • 在前后端分离开发的时候我们需要用到参数校验,前端需要进行参数校验,后端接口同样的也需要,以防传入不合法的数据。 首先还是先导包,导入pom文件。 <dependency> <groupId>org.springframework....
  • SpringBoot注解校验请求参数

    万次阅读 2018-10-08 09:50:58
    常规校验 @RequestMapping( value = "test", method = RequestMethod.POST) public FrogTest test(@RequestBody FrogTest bean) { if (bean.getName() == null) { ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,629
精华内容 5,851
关键字:

springboot参数校验注解

spring 订阅