PS:转自CSDN社区 三毛村滴雪鱼粉

lombok是一个可以帮助我们大幅度简化代码的Java代码工具。
比如JavaBean中private的成员变量需要getter和setter方法,大量的getter和setter方法在一个类中会让我们的类显得非常长。使用lombok工具就可以省去这些代码。

使用方法

在pom文件中添加配置

此处未指定版本,你也可以指定版本

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. </dependency>

idea安装lombok插件

此步骤也可省略,不安装插件只是在idea的Structrue窗口看不到lombok自动生成的方法,安装插件之后可以看到由lombok自动生成的方法。
Spring参数校验机制与LomBok工具集 - 图1
安装步骤
打开设置 =》Plugins ,搜索lombok,点击install,重启idea。
Spring参数校验机制与LomBok工具集 - 图2

常用注解

@Setter 注解在类或字段,注解在类时为所有字段生成setter方法,注解在字段上时只为该字段生成setter方法。
@Getter 注解在类或字段,注解在类时为所有字段生成getter方法,注解在字段上时只为该字段生成getter方法。
@EqualsAndHashCode 注解在类,生成hashCode和equals方法。
@Data 注解在类,生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法。
@AllArgsConstructor 注解在类,生成包含类中所有字段的构造方法。
@RequiredArgsConstructor 注解在类,为类中需要特殊处理的字段生成构造方法,比如final和被@NonNull注解的字段。
@NoArgsConstructor 注解在类,生成无参的构造方法。
@NonNull 注解在类,定义字段不能为空
@Builder 声明实体,表示可以进行Builder方式初始化

@NoArgsConstructor

相当于没使用lombok时的代码

  1. public class PersonDTO {
  2. @NonNull
  3. private String name;
  4. private Integer age;
  5. public PersonDTO() {}
  6. }

@RequiredArgsConstructor

相当于没使用lombok时的代码

  1. public class PersonDTO {
  2. @NonNull
  3. private String name;
  4. private Integer age;
  5. public PersonDTO(String name) {
  6. this.name = name;
  7. }
  8. }

@AllArgsConstructor

相当于没使用lombok时的代码

  1. public class PersonDTO {
  2. @NonNull
  3. private String name;
  4. private Integer age;
  5. public PersonDTO(String name, Integer age) {
  6. this.name = name;
  7. this.age = age;
  8. }
  9. }

@Builder

传统实例化对象的方式

  1. PersonDTO dto = new PersonDTO();
  2. dto.setName("woof");
  3. dto.setAge(18);

使用@Builder模式,这种方式更优雅。但是@Builder会将类的无参构造方法私有化,如果再想使用new PersonDTO();需要自己手动在类中定义一个无参构造方法。如果这个类需要能被当作一个Bean返回到前端还需要能够被序列化,我们需要给类再加一个@Getter。
一般地,我们可以这样设计实体

  1. @Builder
  2. @Getter
  3. public class PersonDTO {
  4. private String name;
  5. private Integer age;
  6. }

Builder模式赋值新对象

  1. PersonDTO dto = PersonDTO.builder()
  2. .name("woof")
  3. .age(18)
  4. .build();

参数校验机制:

参数校验对于我们Web开发是非常重要的。第一,作为服务端的开发者,如果你的参数校验写的足够规范是可以大大提高前后端协同开发的开发效率的,从而为公司及自己大大节约时间成本以及经济成本。第二,参数校验对于保护Web里面的机密数据和机要信息也是非常重要的。校验的代码不能直接写在控制器里。控制器主要是用于承接视图层与服务层之间的桥梁,不是用来编写主要的业务逻辑的,也不是用来写大量的校验的代码的。本文要介绍的参数校验为注解校验的方式。

参数接收

我们要去做参数校验首先要学习的是如何在控制器里能够方便的接收到参数。参数主要分两大类,一类是通过url传递过来的参数,另一类是通过post的body里传递过来的参数。

获取URL路径中的参数和查询参数

url传递的参数也分两种,一种是在路径里的参数,如下面代码中的id1。一种是查询参数,也就是?后面的参数,如下面代码中的name2。路径里的参数通过注解@PathVariable来接收,查询参数可以不用注解,也可以通过加@RequestParam来接收。当参数名与方法中接收参数的参数名不一致时,可以通过在注解后面加name参数来映射。

  1. @GetMapping(value = "/test/{id1}")
  2. public String test(@PathVariable(name="id1") Integer id,@RequestParam(name="name2") String name){

发送请求,请求url为 http://localhost:8080/v1/banner/test/2?name2=雪,查看接收到的参数。
Spring参数校验机制与LomBok工具集 - 图3
Spring参数校验机制与LomBok工具集 - 图4

数据传输对象DTO的接收

当我们要传递大量数据的时候,通常采用POST请求在httpbody中传JSON格式的数据
Spring参数校验机制与LomBok工具集 - 图5
接收这种JSON格式的数据用注解@RequestBody 。接收的数据类型可以定义成一个Map,但是这种方式接收到的参数Object在使用时还需要转型,频繁的拆箱装箱对性能是有一定影响的。我们通常定义一个类来接收参数。

  1. @PostMapping(value = "/test/{id1}")
  2. public PersonDTO test(@PathVariable(name="id1") Integer id,
  3. @RequestParam(name="name2") String name,
  4. @RequestBody Map<String,Object> personDTO){

定义类接收对象

  1. @Getter
  2. @Setter
  3. public class PersonDTO {
  4. private String name;
  5. private Integer age;
  6. }
  7. @PostMapping(value = "/test/{id1}")
  8. public PersonDTO test(@PathVariable(name="id1") Integer id,
  9. @RequestParam(name="name2") String name,
  10. @RequestBody PersonDTO personDTO){

参数校验

基础参数校验

常见注解

  1. Bean validation中内置的constraint
  2. @Null 被注释的元素必须为null
  3. @NotNull 被注释的元素必须不为null
  4. @AssertTrue 被注释的元素必须为true
  5. @AssertFalse 被注释的元素必须为false
  6. @Min(value=) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
  7. @Max(value=) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
  8. @Positive 被注释的元素必须为正数,即数值大于 0
  9. @PositiveOrZero 被注释的元素必须为正数或 0,即数值大于等于 0
  10. @DecimalMin(value=,inclusive=) 被注释的元素必须是一个数字,其值必须大于等于valueinclusive=true,是大于等于
  11. @DecimalMax(value=,inclusive=) 被注释的元素必须是一个数字,其值必须小于等于valueinclusive=true,是小于等于
  12. @Size(min=, max=) 字符串,集合,map 被注释的元素的大小必须在指定的范围内
  13. @Digits(integer,fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
  14. @Past 被注释的元素必须是一个过去的日期
  15. @Future 被注释的元素必须是一个将来的日期
  16. @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
  17. Hibernate validator附加的constraint
  18. @NotBlank(message=) 验证字符串非null,且长度必须大于0
  19. @Email 被注释的元素必须是电子邮箱地址
  20. @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
  21. @NotEmpty 被注释的字符串必须非空
  22. @Range(min=,max=,message=) 被注释的元素必须在合适的范围内

基本使用方式
要想开启参数校验,需要在类上标注@Validated注解

  1. @Validated
  2. public class BannerController {
  3. @PostMapping(value = "/test/{id1}")
  4. public PersonDTO test(@PathVariable(name="id1") @Range(min = 1,max = 10,message = "不能超过10噢") Integer id){

验证HTTP Body中的参数与级联校验

如果要开启Http Body中的参数校验,那么在参数列表该字段前加上@Validated即可

  1. @Validated
  2. public class BannerController {
  3. @PostMapping(value = "/test")
  4. public PersonDTO test(@RequestBody @Validated PersonDTO personDTO){

如果一个类中包含了另外一个实体类,那么在上面加上@Valid即可

  1. public class PersonDTO {
  2. @Valid
  3. private SchoolDTO schoolDTO;
  4. }

自定义校验注解

当基础的校验注解不能满足我们自己的业务需求时,我们就需要自定义注解了。
1.创建一个注解
@Documented 注解标记的元素,Javadoc工具会将此注解标记元素的注解信息包含在javadoc中。默认,注解信息不会包含在Javadoc中。
@Retention({RetentionPolicy.Runtime}) RetentionPolicy这个枚举类型的常量描述保留注释的各种策略,它们与元注释(@Retention)一起指定注释要保留多长时间
@Target({ElementType.TYPE}) 用于描述注解可以用在什么地方
@Constraint(validatedBy = PasswordValidator.class)将自定义校验注解与关联类关联在一起。validatedBy接收的参数可以是一个数组,也就是可以指定多个关联类来修饰这个自定义注解

  1. import javax.validation.Constraint;
  2. import javax.validation.Payload;
  3. import java.lang.annotation.*;
  4. @Documented
  5. @Retention(RetentionPolicy.RUNTIME)
  6. @Target(ElementType.TYPE)
  7. @Constraint(validatedBy = PasswordValidator.class)
  8. public @interface PasswordEqual {
  9. int min() default 2;
  10. int max() default 10;
  11. String message() default "passwords are not equal";
  12. Class<?>[] groups() default {};
  13. Class<? extends Payload>[] payload() default {};
  14. }

2.创建关联类
自定义校验注解还需要一个关联类,校验的业务逻辑应该写在关联类中。关联类要实现ConstraintValidator这个接口,这个接口是一个泛型类,第一个参数是注解的类型,第二个参数是这个自定义注解所修饰的目标的类型。重写initialize()方法,在initialize()方法中获取注解的参数。重写isValid()方法校验参数是否通过校验

  1. import com.lin.missyou.dto.PersonDTO;
  2. import javax.validation.ConstraintValidator;
  3. import javax.validation.ConstraintValidatorContext;
  4. public class PasswordValidator implements ConstraintValidator<PasswordEqual, PersonDTO> {
  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. @Override
  14. public boolean isValid(PersonDTO personDTO, ConstraintValidatorContext constraintValidatorContext) {
  15. String password1 = personDTO.getPassword1();
  16. String password2 = personDTO.getPassword2();
  17. boolean match = password1.equals(password2);
  18. return match;
  19. }
  20. }