美文网首页
springMVC请求参数校验

springMVC请求参数校验

作者: 水煮鱼又失败了 | 来源:发表于2021-03-21 20:07 被阅读0次

    下下下周,争取做只水煮鱼~~~
    算了吧,买现成的调料吧~~~


    fish.png

    1 场景

    JavaWeb后台应用程序,具体的执行方法,收到请求,需要对请求的数据进行基础校验,如字符串长度限制、正则校验、数字区间校验等。

    推荐在springMVC中对前台的请求参数进行统一校验,校验方式建议采用JSR30标准进行校验。

    1.1 普通校验方式

    最简单的校验方式是,对请求的参数手动一个个进行校验,如下代码:

    @GetMapping("saveWithOld")
    public JSONObject saveWithOld(User user) {
        JSONObject result = new JSONObject();
        if (user.getUserCode() == null || user.getUserCode() == "") {
            result.put("success", true);
            result.put("message", "用户代码不可为空");
            return result;
        }
        if (user.getUserName() == null || user.getUserName() == "") {
            result.put("success", true);
            result.put("message", "用户名称不可为空");
            return result;
        }
        // do something ......
    
        result.put("success", true);
        return result;
    }
    

    这种方式,代码量非常大代码非常不友好

    1.2 springMVC校验方式

    springMVC,在执行后台方法之前,可以对请求的数据通过注解进行校验。此校验方式基于JSR303规范

    如下代码所示:

    @Data
    public class User {
        @NotNull(message = "用户代码不可为空")
        private String userCode;
    }
    
    @GetMapping("saveWithNormal")
        public JSONObject saveWithNormal(@Valid User user) {
            JSONObject result = new JSONObject();
            result.put("success", true);
            result.put("message", user.toString());
            return result;
        }
    
    @PostMapping("saveWithRequestParam")
    public JSONObject saveWithRequestParam(@NotNull(message = "用户代码不可为空") String userCode) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        result.put("message", userCode);
        return result;
    }
    

    此种方式,可以使用注解,已更简单的方式对请求参数进行校验。

    3 版本说明

    本文中代码涉及到的相关版本如下:

    3.1 JDK

    JDK1.8

    3.2 maven依赖

    spring-boot-starter-web中已包含了我们需要的依赖。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.2.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.7 </version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.18</version>
        <scope>provided</scope>
    </dependency>
    

    2 名词关系说明

    这里讲下springMVC中使用JSR303进行参数校验,相关的名词含义及名词之间的关系说明

    2.1 基本说明

    springMVC基于JSR303规范进行校验。

    官网说明:https://jcp.org/en/jsr/detail?id=303

    规范的相关说明如下:

    JSR是Java Specification Requests的缩写,意思是Java 规范提案 。
    JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation
    Hibernate Validator是 Bean Validation的参考实现
    Hibernate Validator提供了JSR 303 规范中所有内置 constrain(约束)的实现,除此之外还有一些附加的constraint(约束)

    2.2 详细说明

    关于springMVC请求参数校验,涉及几个对应的名词,如下是:

    名词 说明
    constraint(约束) 对参数的校验约束注解,如@NotNull表示参数不可以为Null
    校验注解 为元素加上约束后,有时候需要在参数前加上校验注解来开启验证。
    相关注解有@Valid@Validated,如没有用到注解独有的特性(分组、嵌套)等,用哪个注解都一样。

    需注意不是所有的校验都需要开启校验,如下不需要加上校验注解:
    saveWithRequestParam(@NotNull(message = "用户代码不可为空") String userCode)
    但是需要在Controller类上加上注解@Valid或@Validated
    JSR303规范 行业规范标准,包括校验的constraint(约束,如@NotNull)开启校验注解@Valid
    体现:代码中体现为注解、接口无具体实现代码
    jar包:jakarta.validation-api-2.0.2.jar
    约束注解:javax.validation.constraints包下注解+hibernate增强注解org.hibernate.validator.constraints
    校验注解:javax.validation.Valid
    Hibernate Validator Hibernate对JSR303规范中的约束constraint具体代码实现
    jar包:hibernate-validator-6.0.20.Final.jar
    增强:在原有JSR303的constraint(约束)增加了约束(如@Range)
    spring JSR303 spring对JSR303的包装,对原有的校验进行了增强
    增强:分组校验顺序校验
    缺点:不支持嵌套校验
    约束注解:javax.validation.constraints包下注解+hibernate增强注解org.hibernate.validator.constraints
    校验注解:org.springframework.validation.annotation.Validated
    增强说明:所谓的包装和增强,只是将@Valid注解扩展为@Validated注解。约束注解和JSR303一样。

    2.3 关系图

    一图胜千言。参数校验的相关说明,关系图如下:

    spring参数校验.jpg

    3 校验流程

    3.1 对象参数

    3.1.1 说明

    对象参数中进行约束校验。需满足以下条件:

    (1)在mapping方法中通过注解@Valid或@Validated指定要校验的参数对象

    如下:

    @GetMapping("saveWithNormal")
    public JSONObject saveWithNormal(@Valid User user) {......}
    

    (2)在对象参数对应的类中,对需要校验的参数加上约束注解

    如下:

    @Data
    public class User {
        /**
         * 用户代码
         */
        @NotNull(message = "用户代码不可为空")
        private String userCode;
    }
    
    3.1.2 校验流程

    校验失败后,需要对失败的异常信息进行处理,处理方式有两种:

    1、在mapping方法上加上参数BindingResult bindingResult

    此种方式,校验失败后,会将异常信息封装到参数对象bindingResult中,可以自行对其中的异常信息进行处理,封装错位信息,返回请求结果

    这种情况,需要每个请求,都对参数BindingResult进行处理,较为繁琐,不建议此种方式。

    如下:

    @GetMapping("saveWithBind")
    public JSONObject saveWithBind(@Valid User user, BindingResult bindingResult) {
        // --------------------[手动检测验证是否通过]--------------------
        if (bindingResult.hasErrors()) {
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                JSONObject result = new JSONObject();
                result.put("success", false);
                result.put("message", fieldError.getDefaultMessage());
                return result;
            }
        }
        // --------------------[验证检测通过后执行其他操作]--------------------
        // ......
        JSONObject result = new JSONObject();
        result.put("success", true);
        result.put("message", user.toString());
        return result;
    }
    

    2、定义spring全局异常处理,捕捉对应的异常信息,进行统一处理

    mapping方法上不加参数BindingResult bindingResult,校验失败后,会抛出异常,异常信息,通过spring全局异常管理,统一对抛出的异常信息进行处理,处理后统一封装错位信息。这种方式,代码量较少,且处理错误信息集中,推荐此种方式。

    如下代码:

    @Data
    public class User {
        /**
         * 用户代码
         */
        @NotNull(message = "用户代码不可为空")
        private String userCode;
    }
    
    // 参数校验失败,抛出异常:org.springframework.validation.BindException
    @GetMapping("saveWithNormal")
    public JSONObject saveWithNormal(@Valid User user) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        result.put("message", user.toString());
        return result;
    }
    
    /**
       * 捕捉全局异常:org.springframework.validation.BindException
       * <div>普通请求的参数,校验失败,抛出此异常</div>
       * <div>如:(@Valid User user)</div>
       *
       * @param exception
       * @return
       */
    @ExceptionHandler(BindException.class)
    public JSONObject handlerBindException(BindException exception) {
        log.info("全局异常[BindException]:" + exception.getMessage());
        JSONObject result = new JSONObject();
        result.put("success", false);
        if (exception != null) {
            String message = exception.getBindingResult().getFieldErrors().stream().filter(e -> e != null).map(FieldError::getDefaultMessage).collect(Collectors.joining(","));
            result.put("message", message);
        }
        return result;
    }
    

    需注意:参数上@Valid和@Validated使用方式的不同,校验失败后,会抛出不同的异常

    如下:

    /**
      * 捕捉全局异常:org.springframework.validation.BindException
      * <div>普通请求的参数,校验失败,抛出此异常</div>
      * <div>如:(@Valid User user)</div>
      * @param exception
      * @return
      */
    @ExceptionHandler(BindException.class)
    public JSONObject handlerBindException(BindException exception) {......}
    
    /**
      * 捕捉全局异常:org.springframework.web.bind.MethodArgumentNotValidException
      * <div>@RequestBody修饰的参数,校验失败,抛出此异常</div>
      * <div>如:(@RequestBody @Valid User user)</div>
      * @param exception
      * @return
      */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public JSONObject handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) {......}
    

    总结校验流程图如下:

    对象参数校验流程.jpg

    3.2 普通类型参数

    3.2.1 说明

    普通类型参数中进行约束校验。需满足以下条件:

    (1)在Controller类上通过注解@Validated开启校验

    注意:需为@Validated注解,而不是@Valid注解

    如下:

    @Validated
    @RestController
    @RequestMapping("user")
    public class UserController {......}
    

    (2)在mapping方法普通类型参数前面加上约束注解

    如下:

    // 参数校验失败,抛出异常:javax.validation.ConstraintViolationException
    @PostMapping("saveWithRequestParam")
    public JSONObject saveWithRequestParam(@NotNull(message="用户代码不可为空") String userCode){......}
    
    // 参数校验失败,抛出异常:org.springframework.web.bind.ConstraintViolationException
    @GetMapping("saveWithRestful/{userCode}")
    public JSONObject saveWithRest(@PathVariable("userCode") @Length(max = 10,message="用户代码不可超过10位") String userCode) {......}
    
    3.2.1 校验流程

    校验结果的处理流程同《3.1对象参数》

    需注意:如使用全局异常捕捉,校验失败后抛出的异常如下:

     /**
       * 捕捉全局异常:javax.validation.ConstraintViolationException
       * <div>直接在参数上加的校验,校验失败,抛出此异常</div>
       * <div>如:(@NotNull(message = "用户代码不可为空") String userCode)</div>
       *
       * @param exception
       * @return
       */
    @ExceptionHandler(ConstraintViolationException.class)
    public JSONObject handlerConstraintViolationException(ConstraintViolationException exception) {......}
    

    总结校验流程图如下:

    普通参数校验流程.jpg

    4 嵌套校验

    嵌套校验,准确来说,是对象内约束的嵌套校验。指的是校验A对象,A对象内有个属性B是对象,B对象内部属性仍然有约束。需要对A对象的约束+A对象内B对象的约束进行校验,这种就是嵌套约束。

    4.1 代码示例

    这里既校验参数user中的userCode约束又需要校验user中的属性对象department中的departmentCode的约束

    • 实体定义
    @Data
    public class Department {
        @NotNull(message = "部门代码不可为空")
        private String departmentCode;
    }
    
    @Data
    public class User {
        @NotNull(message = "用户代码不可为空")
        private String userCode;
        
        @Valid
        @NotNull(message = "部门不可为空")
        private Department department;
        
        private String userName;
    }
    
    • mapping方法
    @GetMapping("saveWithLevel")
    public JSONObject saveWithLevel(@Valid User user) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        result.put("message", user.toString());
        return result;
    }
    
    • 异常处理
    @ExceptionHandler(BindException.class)
    public JSONObject handlerBindException(BindException exception) {
        log.info("全局异常[BindException]:" + exception.getMessage());
        JSONObject result = new JSONObject();
        result.put("success", false);
        if (exception != null) {
            String message = exception.getBindingResult().getFieldErrors().stream().filter(e -> e != null).map(FieldError::getDefaultMessage).collect(Collectors.joining(","));
            result.put("message", message);
        }
        return result;
    }
    

    4.2 代码测试

    • 请求信息

    http://localhost:8080/user/saveWithLevel?department.departmentCode=001

    • 返回结果
    {"success":false,"message":"部门代码长度需在5~10之间,用户代码不可为空"}
    

    可见嵌套校验起作用了,对象user的内部普通属性userCode和内部对象department的自己的约束都起作用了。

    4.3 总结

    • 实现嵌套校验,在被校验对象的内部属性对象上,必须加上@Valid注解

    • mapping方法参数前,用@Valid注解和@Validated没有区别

    5 分组校验

    同一个javaBean,我们加上约束注解后,这个javaBean作为请求参数的对象类型,其中的约束注解,会对参数对象的内容进行校验。

    有时候,不同的请求我们会使用相同的javaBean作为对象的参数类型,如新增用户更新用户我们都会使用用户这个JavaBean作为请求参数的封装对象。

    5.1 代码示例

    比如,我们新增用户,需要设置密码;更新用户,不需要设置密码。

    代码如下:

    • 分组类型

    分组接口不需要有实现,仅仅作为一个分组类型

    public interface Add {
    }
    
    public interface Edit {
    }
    
    • 实体定义

    通过约束中的group参数,来指定对应的分组类型,可以指定多个

    @Data
    public class User {
        @NotNull(message = "用户代码不可为空", groups = {Add.class, Edit.class})
        private String userCode;
        
        @NotNull(message = "密码不可为空", groups = {Add.class})
        private String password;
    }
    
    • mapping方法

    校验方式,只能指定@Validated,其中的value为这个参数的分组类型,和类中约束注解的groups属性相对性可以指定多个

    @GetMapping("groupAdd")
    public JSONObject groupAdd(@Validated(Add.class) User user) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        result.put("message", user.toString());
        return result;
    }
    
    @GetMapping("groupEdit")
    public JSONObject groupEdit(@Validated(Edit.class) User user) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        result.put("message", user.toString());
        return result;
    }
    
    • 异常处理

    同4.1

    5.2 代码测试

    5.3 总结

    (1)分组校验中,定义的分组类型接口,不需要有实现内容,仅仅是作为分组的一个类型存在,不同的业务,可以共用相同的类型。

    (2)约束中的分组类型,可以定义多个。

    (3)@Validated中的分组类型,也可以指定多个。

    (4)校验的时候,根据@Validated中指定分组类型,去找校验对象中的对应有此分组类型的约束,进行校验。

    (5)指定分组后,不满足分组的约束(不加分组的约束为默认分组,也是一种分组),不会进行校验

    6 顺序校验

    如不进行顺序校验配置,校验对象内的属性,校验顺序是随机的。

    有时候想先校验比较简单的约束,再校验复杂的,因此需要指定约束的校验顺序。可以结合《7 验证将检测到第一个约束违例时停止》一起使用。

    6.1 代码示例

    • 分组类型
    // 分组类型:第一个执行
    public interface FirstCheck {
    }
    
    // 分组类型:第二个执行
    public interface SecondCheck {
    }
    
    // 待顺序的分组类型组
    @GroupSequence({FirstCheck.class, SecondCheck.class})
    public interface UserGroupCheck {
    }
    
    • 实体定义
    @Data
    public class User {
        @NotNull(message = "用户代码不可为空", groups = {FirstCheck.class})
        private String userCode;
        
        @NotNull(message = "密码不可为空", groups = {SecondCheck.class})
        private String password;
        
        @NotNull(message = "用户名不可为空")
        private String userName;
    }
    
    • mapping方法
    @GetMapping("orderCheck")
    public JSONObject orderCheck(@Validated(UserGroupCheck.class) User user) {
        JSONObject result = new JSONObject();
        result.put("success", true);
        result.put("message", user.toString());
        return result;
    }
    
    • 异常处理

    同4.1

    6.2 代码测试

    • 请求1

      • 请求

      http://localhost:8080/user/orderCheck

      • 结果
      {"success":false,"message":"用户代码不可为空"}
      
    • 请求2

      • 请求

      http://localhost:8080/user/orderCheck?userCode=001

      • 结果
      {"success":false,"message":"密码不可为空"}
      

      请求3

      • 请求

      http://localhost:8080/user/orderCheck?userCode=001&password=123456

      • 结果
      {"success":true,"message":"User(userCode=001, password=123456, userName=null)"}
      
    • 特殊请求

      • 变更

        将实体类进行变更,userName上的约束也加上分组为FirstCheck。此时userCode和userName的约束分组均为FirstCheck。

        如下:

        @Data
        public class User {
            @NotNull(message = "用户代码不可为空", groups = {FirstCheck.class})
            private String userCode;
            
            @NotNull(message = "密码不可为空", groups = {SecondCheck.class})
            private String password;
            
            @NotNull(message = "用户名不可为空", groups = {FirstCheck.class})
            private String userName;
        }
        
      • 请求

        http://localhost:8080/user/orderCheck

      • 结果

    {"success":false,"message":"用户代码不可为空,用户名不可为空"}

    
    或
    
    ```json
    {"success":false,"message":"用户名不可为空,用户代码不可为空"}
    

    可以看出,当一个分组内有多个约束,约束的校验顺序仍然是随机的

    6.3 总结

    (1)根据参数中的分组对应的接口中@GroupSequence指定的分组类型的顺序进行加校验

    (2)只有当一个分组内的所有约束都校验通过后,才会进入下一个分组进行校验。

    (3)顺序校验,指的是@GroupSequence内配置的分组的顺序,当一个分组内有多个约束这个分组内约束校验顺序仍然随机

    7 验证将检测到第一个约束违例时停止

    默认,有多个约束的情况下,将会对所有参数进行校验,如果存在校验失败的约束,返回的校验结果(BindingResult或对应Exception)中会有所有的参数校验错误信息。即如果多个不满足约束,则返回结果中会有多个失败信息

    有时候,我们只需要返回第一个一个校验失败的约束信息就好,校验到一个约束失败后,没有必要再花费代价进行其他约束校验。

    springBoot中,参数校验的实现,基于MethodValidationPostProcessor

    @Bean
    @ConditionalOnMissingBean
    public static MethodValidationPostProcessor methodValidationPostProcessor(Environment environment,
                                                                              @Lazy Validator validator) {
        MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
        boolean proxyTargetClass = environment.getProperty("spring.aop.proxy-target-class", Boolean.class, true);
        processor.setProxyTargetClass(proxyTargetClass);
        processor.setValidator(validator);
        return processor;
    }
    

    这个postProcessor的校验配置基于spring中的beanValidator,我们创建自己的Validator的bean,配置failFast,即可实现验证将检测到第一个约束违例时停止这个要求。

    实现代码如下:

    @Bean
    public Validator validator() {
        HibernateValidatorConfiguration configuration = Validation.byProvider(HibernateValidator.class).configure();
        //验证将检测到第一个约束违例时停止
        configuration.failFast(true);
        ValidatorFactory validatorFactory = configuration.buildValidatorFactory();
        return validatorFactory.getValidator();
    }
    

    或使用更简洁的写法:

    @Bean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
            .configure()
            //验证将检测到第一个约束违例时停止
            .failFast(true)
            .buildValidatorFactory();
        return validatorFactory.getValidator();
    }
    

    failFastHibernateValidatorConfiguration中的一个属性配置,配置中还有其他配置属性,可以定制我们的校验器

    8 自定义校验器

    自定义校验器,注意点比较多,不是本文的重点,暂时不进行记录,后续有时间会有专门的文章进行分析。

    9 生产环境配置

    前面说的都是原理和使用细节,这里记录下生产环境,需要进行哪些全局配置。

    9.1 全局异常处理

    建议使用全局异常处理,对请求的异常信息进行统一处理。

    代码如下:

    import com.alibaba.fastjson.JSONObject;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.validation.BindException;
    import org.springframework.validation.FieldError;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    
    import javax.validation.ConstraintViolation;
    import javax.validation.ConstraintViolationException;
    import java.util.stream.Collectors;
    
    /**
     * 统一异常处理
     */
    @Slf4j
    @RestControllerAdvice
    public class GlobalExceptionHandler {
        
        /**
         * 捕捉全局异常:org.springframework.web.bind.MethodArgumentNotValidException
         * <div>@RequestBody修饰的参数,校验失败,抛出此异常</div>
         * <div>如:xxxAction(@RequestBody @Valid User user)</div>
         * @param exception
         * @return
         */
        @ExceptionHandler({MethodArgumentNotValidException.class})
        public JSONObject handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) {
            log.info("全局异常[MethodArgumentNotValidException]:" + exception.getMessage());
            JSONObject result = new JSONObject();
            result.put("success", false);
            if (exception != null) {
                String message = exception.getBindingResult().getFieldErrors().stream().filter(e -> e != null).map(FieldError::getDefaultMessage).collect(Collectors.joining(","));
                result.put("message", message);
            }
            return result;
        }
        
        /**
         * 捕捉全局异常:org.springframework.validation.BindException
         * <div>普通请求的参数,校验失败,抛出此异常</div>
         * <div>如:xxxAction(@Valid User user)</div>
         * @param exception
         * @return
         */
        @ExceptionHandler(BindException.class)
        public JSONObject handlerBindException(BindException exception) {
            log.info("全局异常[BindException]:" + exception.getMessage());
            JSONObject result = new JSONObject();
            result.put("success", false);
            if (exception != null) {
                String message = exception.getBindingResult().getFieldErrors().stream().filter(e -> e != null).map(FieldError::getDefaultMessage).collect(Collectors.joining(","));
                result.put("message", message);
            }
            return result;
        }
        
        /**
         * 捕捉全局异常:javax.validation.ConstraintViolationException
         * <div>直接在参数上加的校验,校验失败,抛出此异常</div>
         * <div>如:xxxAction(@NotNull(message = "用户代码不可为空") String userCode)</div>
         * <div>如:xxxAction(@PathVariable("userCode") @Length(max = 10,message="用户代码不可超过10位") String userCode)</div>
         * @param exception
         * @return
         */
        @ExceptionHandler(ConstraintViolationException.class)
        public JSONObject handlerConstraintViolationException(ConstraintViolationException exception) {
            log.info("全局异常[ConstraintViolationException]:" + exception.getMessage());
            JSONObject result = new JSONObject();
            result.put("success", false);
            if (exception != null) {
                result.put("message", exception.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining(";")));
            }
            return result;
        }
        
    }
    

    参数校验失败,返回的错误json信息如下,可以根据项目的实际情况进行定制:

    {"success":false,"message":"用户代码不可超过10位"}
    

    9.2 验证将检测到第一个约束违例时停止

    import org.hibernate.validator.HibernateValidator;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.validation.Validation;
    import javax.validation.Validator;
    import javax.validation.ValidatorFactory;
    
    @Configuration
    public class ValidConfig {
        @Bean
        public Validator validator() {
            ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                    .configure()
                    //验证将检测到第一个约束违例时停止
                    .failFast(true)
                    .buildValidatorFactory();
            return validatorFactory.getValidator();
        }
    }
    

    10 补充

    10.1 校验限制

    @Valid支持嵌套验证、@Validated支持分组验证排序验证(准确来说,排序验证也是分组验证的一种)。

    无法实现:“嵌套验证+分组验证”和“嵌套验证+排序验证”这种组合形式的验证。

    10.2 建议

    虽然JSR303支持自定义校验器,笔者不建议将太复杂的校验交给JSR303的标准进行校验

    如果是参数基本的属性校验(是否为空、长度、大小、枚举、正则格式),可以以这种形式进行校验。

    但是如果是太复杂的校验,如需要连接数据库进行业务判断的校验,笔者仍然建议在具体的业务代码中进行校验。

    10.2 校验顺序的随机性

    如不使用@Validated指定约束的校验顺序,所有约束的校验顺序是随机的,即相同的情况,返回的校验结果的顺序可能不一样。

    10.3 一个字段多个约束

    同一个字段可以加多个约束注解,并不是只能有一个约束注解。如下:

    @NotNull(message = "用户代码不可为空")
    @Length(min = 5, max = 10, message = "用户代码长度需在5~10之间")
    private String userCode;
    

    如userCode为空,则抛出异常:用户代码不可为空

    如userCode不为空,则校验约束:用户代码长度需在5~10之间

    相关文章

      网友评论

          本文标题:springMVC请求参数校验

          本文链接:https://www.haomeiwen.com/subject/zbsocltx.html