精华内容
下载资源
问答
  • 校验对象
    千次阅读
    2019-10-24 17:26:22
    public Object testOne(@RequestBody @Valid Dto dto) {}
    
    public class Dto {
        private Student student;
        @Valid
        private Teacher teacher;
        }
    
    public class Teacher {
    
        @NotNull(message = "教师id不能为空")
        private Integer id;
        @NotBlank(message = "教师名字不能为空")
        private String teacherName;
        }
    

    从上至下,都加上@valid,直到我们最终的需要校验的那个对象(其他对象的属性)

    如此@Valid才会生效

    更多相关内容
  • 比如校验对象属性是否为空。 一、自定义一个NotNull注解 我们自定义一个NotNull注解,里面有一个参数message 默认为“”; /** * 自定义注解 * 判断屬性不为空注解 */ @Retention(RetentionPolicy.RUNTIME) @...

    前面学习了如何自定义一个注解:java如何优雅的自定义一个注解
    下面来实战演示一下如何使用自定义注解做一些实际的功能。比如校验对象属性是否为空。

    一、自定义一个NotNull注解

    我们自定义一个NotNull注解,里面有一个参数message 默认为“”;

    /**
     * 自定义注解
     * 判断屬性不为空注解
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface NotNull {
        /**
         * 如果字段有该注解,判断为空并返回异常信息
         */
        String message() default "";
    }
    

    二、创建实体对象Student

    创建一个Student对象,有两个属性name、age,并给属性设置刚才自定义的NotNull 注解,
    可以设置message信息,也可不设置。

    package com.example.demo1.annotation;
    
    /**
     * 学生
     * create by c-pown on 2020-07-03
     */
    public class Student {
    
        @NotNull
        private String name;
    
        @NotNull(message = "age is null")
        private Integer age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    

    三、解析校验Student对象

    创建checkUserFiled方法校验对象属性是否为空,如果有使用NotNull注解的属性为空,则抛出异常。如果没有使用NotNull注解则不校验。

    • Class<?> aClass = t.getClass();传入对象class。
    • Field[] declaredFields = aClass.getDeclaredFields();获取当前对象所有属性 使用带Declared的方法可访问private属性
    • 遍历对象属性Field
    1. field.setAccessible(true);开启访问权限,如果不设置,无法访问private注解。
    2. Object o = field.get(t);使用此方法 field.get(Object obj) 可以获取 当前对象这个属性的值
    3. Annotation annotation = field.getDeclaredAnnotation(NotNull.class);获取NotNull注解。如果没有设置当前注解 不用校验
    4. 校验注解。
    package com.example.demo1.annotation;
    
    import org.apache.commons.lang3.StringUtils;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Field;
    
    /**
     * 校验对象属性是否为null
     * create by c-pown on 2020-07-03
     */
    public class AnnotationTest {
       
        /**
         * 判断类属性是否为空
         * @param t
         * @param <T>
         * @throws RuntimeException
         */
        public static <T>  void checkUserFiled(T t) throws RuntimeException, IllegalAccessException {
    
            if(null == t){
                throw  new RuntimeException("obj is null");
            }
            //获取class对象
            Class<?> aClass = t.getClass();
            //获取当前对象所有属性  使用带Declared的方法可访问private属性
            Field[] declaredFields = aClass.getDeclaredFields();
            //遍历对象属性
            for (Field field : declaredFields) {
                //开启访问权限
                field.setAccessible(true);
                //使用此方法 field.get(Object obj) 可以获取  当前对象这个列的值
                Object o = field.get(t);
                Annotation annotation = field.getDeclaredAnnotation(NotNull.class);
                //如果没有设置当前注解 不用校验
                if(annotation == null){
                    continue;
                }
                //获取注解接口对象
                NotNull notNull = (NotNull)annotation;
                //如果设置了当前注解,但是没有值,抛出异常
                if(o == null){
                    if(StringUtils.isNotBlank(notNull.message())){
                        //设置了注解message值 直接返回
                        throw new RuntimeException(notNull.message());
                    }else{
                        //没有设置可以拼接
                        throw new RuntimeException(field.getName()+" is null");
                    }
                }
            }
        }
    }
    

    测试:

     public static void main(String[] args) {
            Student student = new Student();
    //        student.setName("张三");
    //        student.setAge(18);
            try {
                checkUserFiled(student);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }catch (RuntimeException e){
                e.printStackTrace();
            }
            System.out.println(student);
        }
    

    在这里插入图片描述

    设置name属性部位空,age为空。
    
        Student student = new Student();
            student.setName("张三");
    //        student.setAge(18);
    

    在这里插入图片描述
    全部设置:

    Student student = new Student();
            student.setName("张三");
            student.setAge(18);
    

    在这里插入图片描述
    没有问题的。

    使用反射可以对注解信息进行解析,在通过初始化调用可以对注解信息进行校验。实现注解的功能性。

    展开全文
  • 最近做一个项目,用的...在参数校验这块使用了spring-boot-starter-validation注解校验参数,可避免业务代码中无休止的参数校验判断,但在分层的方面来说,参数校验一般都是在Controller层完成的,但这一次情况...

    最近做一个项目,用的springboot2.2.0.RELEASE+mybatisplus3.2.0架构,想着springboot这么强大了,里面有的功能都得用上秀一把技,结果翻车了。

    在参数校验这块使用了spring-boot-starter-validation注解校验参数,可避免业务代码中无休止的参数校验判断,但在分层的方面来说,参数校验一般都是在Controller层完成的,但这一次情况特殊:提供的是dubbo服务。

    话不多说,直接上代码

    ValidGroup代码

    public class ValidGroup {
    
        public interface Insert extends Default {
        }
    
        public interface Update extends Default {
        }
    
    
    }

    model代码

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    @TableName("brand")
    public class Brand extends BaseModel {
    
        @TableId(value = "id", type = IdType.AUTO)
        @NotNull(message = "{Brand.id.null}", groups = {ValidGroup.Update.class})
        private Long id;
    
        @NotBlank(message = "{Brand.brandCode.null}")
        @Size(min = 5, max = 5, message = "{Brand.brandCode.size}", groups = {ValidGroup.Insert.class, ValidGroup.Update.class})
        @TableField
        private String brandCode;
    
        @NotBlank(message = "{Brand.brandName.null}")
        @Size(min = 1, max = 50, message = "{Brand.brandName.size}", groups = {ValidGroup.Insert.class, ValidGroup.Update.class})
        private String brandName;
    
        @NotBlank(message = "{Brand.brandEnName.null}")
        @Size(min = 1, max = 50, message = "{Brand.brandEnName.size}", groups = {ValidGroup.Insert.class, ValidGroup.Update.class})
        private String brandEnName;
    
        @NotBlank(message = "{Brand.brandType.null}")
        @Size(min = 1, max = 50, message = "{Brand.brandType.size}", groups = {ValidGroup.Insert.class, ValidGroup.Update.class})
        private String brandType;
    
        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
        @JSONField(format = "yyyy-MM-dd HH:mm:ss")
        private Date updateTime;
    
    }

    service层代码

    V1初始没分组时代码

    @Validated
    @Service
    public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements BrandService {
    
        @Override
        public Brand getBrandByCode(String brandCode) {
            return getById(brandCode);
        }
    
        @Override
        public boolean saveBrand(@Valid Brand brand) {
            return save(brand);
        }
    
        @Override
        public boolean updateBrand(@Valid Brand brand) {
            return updateById(brand);
        }
    
    
    }

    V2有分组时代码

    @Validated
    @Service
    public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements BrandService {
    
        @Override
        public Brand getBrandByCode(String brandCode) {
            return getById(brandCode);
        }
    
        @Override
        public boolean saveBrand(@Validated({ValidGroup.Insert.class}) Brand brand) {
            return save(brand);
        }
    
        @Override
        public boolean updateBrand(@Validated({ValidGroup.Update.class}) Brand brand) {
            return updateById(brand);
        }
    
    
    }

    V1版本是可以校验住的,只是在修改的方法里有些字段要排除掉,为了解决差异引入了分组,V2版本添加了分组后就直接提交给测试了。

    过了没多久,来了一个bug,说创建和修改都失效了。。。

     

    检查写法,百度,发现基本都是这样的写法

    。。。。

    检查了MethodValidationPostProcessor和MethodValidationInterceptor,一步步debug,没找到原因。。。

    因有排期,所以就先用了if else搞定了校验。

     

    正好今天他有空,之前排查打开的网页还没关,正好接着排查。

    其中看到了

    https://blog.csdn.net/blueheart20/article/details/88817754

    https://reflectoring.io/bean-validation-with-spring-boot/

    才发现写法有问题

    后来换了写法搞定了

    @Validated
    @Service
    public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements BrandService {
    
        @Override
        public Brand getBrandByCode(@NotBlank String brandCode) {
            return getById(brandCode);
        }
    
        @Override
        @Validated({ValidGroup.Insert.class})
        public boolean saveBrand(@Valid Brand brand) {
            return save(brand);
        }
    
        @Override
        @Validated({ValidGroup.Update.class})
        public boolean updateBrand(@Valid Brand brand) {
            return updateById(brand);
        }
    
    }

     

     

     

    展开全文
  • spring validation校验对象多个字段返回的消息内容顺序随机问题

    问题描述:

    model中的代码如下

    public class User {
    
      @NotNull(message = "id不能为空", groups = UserGroup.UPDATE.class)
      protected Integer id;
      /**
       * 姓名
       */
      @NotBlank(message = "请输入姓名", groups = UserGroup.ADD.class)
      private String name;
      /**
       * 性别
       */
      @NotBlank(message = "请输入性别", groups = UserGroup.ADD.class)
      private String sex;
      /**
       * 手机号
       */
      @NotBlank(message = "请输入手机号", groups = UserGroup.ADD.class)
      private String phone;
      /**
       * 邮箱
       */
      @NotBlank(message = "请输入邮箱", groups = UserGroup.ADD.class)
      private String email;
      /**
       * 公司名
       */
      @NotBlank(message = "请输入公司名", groups = UserGroup.ADD.class)
      private String companyName;
      /**
       * 职务
       */
      @NotBlank(message = "请输入职务", groups = UserGroup.ADD.class)
      private String position;
    }
    

    定义的分组接口如下

    public interface UserGroup {
      interface ADD {
      }
    
      interface UPDATE {
    
      }
    }
    

    在使用Spring@Validated注解对对象中的多个参数进行校验时,在MethodArgumentNotValidException异常拦截器处发现如果有多个条件不符和校验规则的参数,MethodArgumentNotValidException中的bindingResult.getAllErrors()异常消息集合中的数据是按照随机顺序返回的,按照正常逻辑来说,我们肯定是想要按顺序将第一个不符合规范字段错误信息返回给用户。

    解决办法

    经过一番搜索发现可以给类上每个验证的注解都指定不同的group,然后在创建一个interface接口添加@GroupSequence对加在字段上的那些接口进行汇总,如下:

    public interface UserGroup {
      @GroupSequence({ADD.NAME.class,
                      ADD.SEX.class,
                      ADD.PHONE.class,
                      ADD.EMAIL.class,
                      ADD.COMPANY_NAME.class,
                      ADD.POSITION.class})
      interface ADD {
        interface NAME {}
        interface SEX {}
        interface PHONE {}
        interface EMAIL {}
        interface COMPANY_NAME {}
        interface POSITION {}
      }
    
      interface UPDATE {
    
      }
    }
    

    Model

    @NoArgsConstructor
    public class User {
    
      @NotNull(message = "id不能为空", groups = UserGroup.UPDATE.class)
      protected Integer id;
      /**
       * 姓名
       */
      @NotBlank(message = "请输入姓名", groups = UserGroup.ADD.NAME.class)
      private String name;
      /**
       * 性别 1.男 2.女 3.未知
       */
      @NotBlank(message = "请输入性别", groups = UserGroup.ADD.SEX.class)
      private String sex;
      /**
       * 手机号
       */
      @NotBlank(message = "请输入手机号", groups = UserGroup.ADD.PHONE.class)
      private String phone;
      /**
       * 邮箱
       */
      @NotBlank(message = "请输入邮箱", groups = UserGroup.ADD.EMAIL.class)
      private String email;
      /**
       * 公司名
       */
      @NotBlank(message = "请输入公司名", groups = UserGroup.ADD.COMPANY_NAME.class)
      private String companyName;
      /**
       * 职务
       */
      @NotBlank(message = "请输入职务", groups = UserGroup.ADD.POSITION.class)
      private String position;
    }
    

    @GroupSequence注解中指定设置的接口数组顺序,然后在参数进行校验的时候直接在@Validated注解中放入UserGroup.ADD.class这个接口类即可public Result add(@Validated(UserGroup.ADD.class) @RequestBody User user)validation就会按照顺序返回错误信息,在异常拦截器中直接这样取出第一个错误信息即可MethodArgumentNotValidException.getBindingResult().getAllErrors().get(0).getDefaultMessage()

    展开全文
  • java使用注解校验对象属性值数据长度定义注解import java.lang.annotation.*;/*** describe:定义注解* current user Maochao.zhu* current system 2020/11/27*/@Target({ ElementType.FIELD, ElementType.TYPE })@...
  • 解决:uview框架 form表单校验问题 当form属性嵌套对象时未取到值的问题
  • 主要介绍了详解iview的checkbox多选框全选时校验问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • import java.util.Collection; import java.util.Enumeration;...* @Description: 校验对象是否为null */ public final class Validator { /** Don't let anyone instantiate this class. */ pri
  • js校验对象参数说明表.xls,js校验对象使用说明.doc
  • /** * 判断数组中是否有重复 * @param arr 数组 * @param key 要校验的key值 */ isRepeat(arr,key){ var obj = {}; for(let i=0;i<arr.length;i++){ if(obj[arr[i]...
  • IDEA 对象一键set 插件

    2021-07-27 16:07:54
    IDEA 对象一键set 插件IDEA 对象一键set 插件IDEA 对象一键set 插件IDEA 对象一键set 插件IDEA 对象一键set 插件IDEA 对象一键set 插件
  • * @Description: 对象校验器 * http://ifeve.com/use-bean-validation/ * @Date 2020/7/9 * @Version V1.0 **/ public class BeanValidator { /** * 验证某个bean的参数 * @param object 被校验的参数 * @...
  • 明明有值,还校验不通过!!! 代码感觉也没问题,就是不行! 其实原因就是因为对象嵌套太多,导致没有准确定位! 解决 1:需要在prop绑定的时候,把你嵌套的那层加上 2:在rules内也需要把对应的prop绑定值对应上...
  • el-form的rules如何校验多层嵌套对象

    千次阅读 2022-05-13 16:29:29
    el-form的表单校验,通常情况下,都是在校验第一层对象时使用 例如: <el-form ref="form" :model="postData" :rules="rules" class="common-form" label-width="118px" size="mini"> <el-row> <el...
  • 对于前端来的数据,后端难免要进行合法性校验,这里可以采用springboot自带的Validated注解来实现,详细方法如下: 实体类: public class User implements Serializable { // @NotNull(message = "id can not be ...
  • 校验对象属性值是否为空

    千次阅读 2019-07-31 15:08:00
    1.涉及jar包 javax.el.jar javax.el-api.jar hibernate-validator.jar validation-api.jar 2.测试 public class TestValidate { public static void mai...
  • Java 对list对象进行属性校验

    千次阅读 2021-03-16 11:56:18
    ps:对list对象进行属性校验。@Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上@Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上user实体类:package com.lucifer.demo.pojo;...
  • @Valid 校验嵌套对象

    千次阅读 2020-02-28 17:25:05
    参考网上的博客:ValidList 能校验list。 通过测试发现,@Valid只能校验一层。比如我这里有个person对象,里面有个ValidList<Teacher> 属性,Teacher对象里面有个List<Student> 属性。 如果在...
  • @Validated 嵌套对象校验

    千次阅读 2021-02-02 14:16:32
    对象A嵌套对象B,在A对象需要校验注解加入@Valid public class B{ @NotBlank(message = "低档次取值不能为空") private String levelone; @NotBlank(message = "中档次取值不能为空") private String ...
  • 在一些项目开发场景中,一个接口可能需要几个对象模型的参数才能实现业务功能 比如在查询商品时,我们既需要顾客信息模型,也需要商品信息模型 接口做业务的时候,还需要对这两个模型进行属性值的校验 二、...
  • 提交 1、重点是: 给 el-form-item 的 prop="" 设为:prop=“role.roleName” 2、然后在校验规则中:重点要用’ '括起来 rules: { 'role.roleName': [ {required: true, message: '请输入用户名', trigger: 'blur'},...
  • 一、普通一层参数的校验方法是这样的: const rule = { goodsId: { type: 'number', required: true }, name: { type: 'string', required: false }, categoryId: { type: 'number', required: false }, unit...
  • 校验数据对象不能为空

    千次阅读 2020-01-02 18:26:16
    /** * 数据处理类 **/ public class FundManagementHandler { /** * 校验数据对象不能为空 * @param typeOne 类型一 * @param typeTwo 类型二 * @param objects 对象数组 * @author 王超 */ public static boolean ...
  • 今天遇到一个小问题,在使用数据校验框架的时候对于嵌套对象只能校验一层查了一下 有文章说是使用Valid加到嵌套的对象前面试了下,这种方式不行,直接是注解不支持在在当前位置使用(The annotation @Valid is ...
  • 分享一种校验数组对象某属性值重复的思路 数据结构 const data = [ { name: '小明', age: 18 }, { name: '小红', age: 20 }, { name: '小明', age: 22 } ] 实现 /** * 校验有无重复项 * @param...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 334,025
精华内容 133,610
关键字:

校验对象