zoukankan      html  css  js  c++  java
  • 全栈之路-小程序API-SpringBoot项目中参数校验机制与LomBok工具集使用

      参数校验机制在web开发中是非常重要的,每当看到现在所在公司的校验代码,我都有头疼,每一个接口都是重新写参数的校验,有些复杂的接口,参数的校验甚至占了整个接口代码量的挺大一部分的,看着我都有些头疼,我知道可以优化,但是我并不知道该如何优化,正好,七月老师在这个项目中讲解到了这一部分,哈哈哈

    一、参数校验机制探究

      参数校验这个是非常重要的,如果把这个参数校验封装好了,那真的能节省很多代码,而且能够节省很多时间,这个还是非常重要的啊,这里分为参数的传递与参数的校验两部分内容

     1、web开发中参数传递方式

    在springboot中参数的传递基本上和springmvc中是类似的,就是基本上还是那几种的传递方式

    (1)路由中的参数

    举例说明:/v1/banner/test/2 (获取这个路由中的2这个参数)

    在path路径中的参数是可以通过@PathVariable注解来获取的,注意这个可以做一个映射,参数的名的对应

    1     @GetMapping("/test/{id}")
    2     public String test(@PathVariable(name = "id") Integer id) {
    3         diana.r();
    4         throw new ForbiddenException(10001);
    5     }

    (2)路由中的?后面的参数

    举例说明:/v1/banner/test/2?name=ssc (在后台中获取name参数的数值)

    这中类型的参数的获取是利用@RequestParam注解来实现值得获取的,这个就比较简单了

    1     @GetMapping("/test/{id}")
    2     public String test(@PathVariable(name = "id") Integer id, @RequestParam String name) {
    3         diana.r();
    4         throw new ForbiddenException(10001);
    5     }

    (3)获取json格式的参数

    也可以说是获取对象类型的参数,我们后台处理的时候使用对象接收的,但是在页面中进行传递的时候是json格式的参数,这里有一个新的概念,那就是DTO(Data Transfer Object)也就是数据传输对象,之后所有的参数传输对象我们都会用这种统一的格式进行传递

    # DTO例子:(省略get/set方法)

    1 public class PersonDTO {
    2 
    3     private String name;
    4     private Integer age;
    5 }

    # 如何应用DTO对象来进行参数的传输

      这里使用@RequestBody注解进行参数的传输的,用的是数据传输对象PersonDTO来接收参数的

    1     @PostMapping("/test")
    2     public String test(@RequestBody PersonDTO person) {
    3         diana.r();
    4         throw new ForbiddenException(10001);
    5     }

     2、参数校验机制和自定义校验

    (1)基础验证注解

    # 基础的注解就是一些SDK中提供的注解,使用的时候一定要在类上添加@Validated注解,组合使用才能起到作用,否则如果不加上这个注解,是没有作用的

    # http body中参数和级联验证中,这个是稍微复杂一点的业务了,在对象中还有一个属性是对象类型的,这个的验证问题就也不是很复杂

    (2)自定义校验注解

     说明:这里以比较两次输入的密码是否相同来举例,写一个自定义的注解,来实现该功能

    # 首先创建两个属性password1和password2,在PersonDTO类中进行创建的,这里使用了lombok的功能注解,简化getter/setter的代码

     1 @Builder
     2 @Getter
     3 public class PersonDTO {
     4 
     5     @Length(min = 2, max = 10, message = "name长度在2~10之间")
     6     private String name;
     7     private Integer age;
     8 
     9     private String password1;
    10     private String password2;
    11 }

    # 然后创建@PasswordEqual注解,这里需要添加两个特定的属性

     1 @Documented
     2 @Retention(RetentionPolicy.RUNTIME)
     3 @Target(ElementType.TYPE)
     4 public @interface PasswordEqual {
     5 
     6     String message() default "passwords are not equals";
     7 
     8     // 自定义验证注解需要默认增加这两个模板方法的
     9     Class<?>[] groups() default {};
    10     Class<? extends Payload>[] payload() default {};
    11 }

    注意:注解只是一个标记,我们不可以在注解中实现业务逻辑代码,自定义注解是有一个专门的关联类来实现业务逻辑代码的,这是如何进行实现的呢

    # 创建自定义注解的关联类

     1 public class PasswordValidator implements ConstraintValidator<PasswordEqual, PersonDTO> {
     2 
     3     // 泛型中第二个是自定义注解修饰的目标类
     4 
     5     @Override
     6     public boolean isValid(PersonDTO personDTO, ConstraintValidatorContext constraintValidatorContext) {
     7         String password1 = personDTO.getPassword1();
     8         String password2 = personDTO.getPassword2();
     9         boolean match = password1.equals(password2);
    10         return match;
    11     }
    12 
    13 }

    注意:注解和关联类是通过@Constraint注解进行组合在一起的,具体的做法就是在自定义注解中添加一个@Constraint注解指定PasswordValidator类的元类class

     1 @Documented
     2 @Retention(RetentionPolicy.RUNTIME)
     3 @Target(ElementType.TYPE)
     4 @Constraint(validatedBy = PasswordValidator.class)
     5 public @interface PasswordEqual {
     6 
     7     String message() default "passwords are not equals";
     8 
     9     // 自定义注解需要默认增加这两个模板方法
    10     Class<?>[] groups() default {};
    11     Class<? extends Payload>[] payload() default {};
    12 }

    ## 这里设计的很巧妙的,在Java中这种编程模式是很优秀的,springboot中应用了很多这种优秀的编程模式,很清晰,代码可维护性很强

    # 获取自定义校验注解的参数

    在自定义注解中难免会有一些参数,就是在使用自定义注解的时候,我们会添加一些参数,那么如何在关联类中处理这些参数呢?首先我们应该获取到这些参数,重写initialize方法

     1 public class PasswordValidator implements ConstraintValidator<PasswordEqual, PersonDTO> {
     2 
     3     // 泛型中第二个是自定义注解修饰的目标的类型
     4 
     5     private int min;
     6     private int max;
     7 
     8     @Override
     9     public void initialize(PasswordEqual constraintAnnotation) {
    10         this.min = constraintAnnotation.min();
    11         this.max = constraintAnnotation.max();
    12     }
    13 
    14     @Override
    15     public boolean isValid(PersonDTO personDTO, ConstraintValidatorContext constraintValidatorContext) {
    16         String password1 = personDTO.getPassword1();
    17         String password2 = personDTO.getPassword2();
    18         boolean match = password1.equals(password2);
    19         return match;
    20     }
    21 
    22 }

    二、LomBok工具集的使用

     1、lombok在项目中安装

    这个直接就安装在pom.xml文件中就可以了,在pom/xml文件中引入lombok的依赖,但是在idea中查看类的机构的时候,如果不安装lombok的插件的话,是很不方便的,建议在idea中安装一个lombok的插件

    # pom.xml文件中引入(这里没有写版本号,maven自动安装完成就可以了)

    1 <!--lombok maven 依赖-->
    2 <dependency>
    3       <groupId>org.projectlombok</groupId>
    4       <artifactId>lombok</artifactId>
    5 </dependency>

    # IDEA中安装lombok插件(直接在plugins插件市场中搜索就可以,直接安装)

     ## 安装完之后,还需要设置一个地方,具体就是:

     

     这样的话,在查看对象的类结构的时候,当我们使用lombok中的注解的时候,我们就可以正常的看到具体的属性本质是什么样子了

    注意:关于在IDEA中如何查看Structure工具栏,是通过view ---> Tool windows ---> Structure这样查看的

     2、lombok中注解的学习

    (1)@Getter/@Setter注解

     这两个注解就是针对代码中的get/set方法进行简化的

    (2)constructor构造方法注解

    ## @AllArgsConstructor 全参数构造方法

    ## @NoArgsConstructor 无参数构造方法

    ## @RequiredArgsConstructor 部分参数构造器

    (3)@Builder注解构造器模式

      这个使用的方法其实也是很简单的,但是有些需要注意的地方,先看一下这个注解是如何使用的

    1 @Builder
    2 public class PersonDTO {
    3     private String name;  
    4     private Integer age;
    5 }
    1 PersonDTO personDTO = PersonDTO.builder()
    2                 .name("ssc")
    3                 .age(18)
    4                 .build();

    具体对象创建的时候,我们只能使用builder这种方式进行构建,不能通过无参数的构造方法进行构建,因为在给一个对象加上@Builder注解之后,这个对象的无参数的构造方法会被变成私有的,无法使用

    解决办法:继续给这个对象添加注解@Setter和@NoArgsConstructor注解,使其能够无参数构造

    还有一个问题,那就是当这个数据传输对象作为结果返回的时候,我们是需要在加上@Getter注解的,这样的话,才能成功将这个对象进行序列化,前端页面才能成功的将这个结果进行接收

     内容出处:七月老师《从Java后端到全栈》视频课程

    七月老师课程链接:https://class.imooc.com/sale/javafullstack

  • 相关阅读:
    ES5 创建构造函数的私有属性
    js 触发打印操作
    创建 React 项目
    处理因使用 BigInt 等最新语法时 ts 编译报错
    TS 查找第三方声明文件
    Git 撤销工作区中的变动
    Git 查看文件修改状态
    Git 查看用户名和 Email
    查看某个 npm 包的所有发行版版本号,比如 vue
    Git 查看文件修改详情
  • 原文地址:https://www.cnblogs.com/ssh-html/p/12348631.html
Copyright © 2011-2022 走看看