美文网首页
Spring之自定义注解

Spring之自定义注解

作者: wishes丶啊 | 来源:发表于2021-03-31 19:59 被阅读0次

写Spring项目的接口中要经常接收前端传过来的参数,要判断参数是否有效,比如邮箱格式要正确,名字不能为空等等。

手动判断比较麻烦,我们可以通过注解的方式来判断值是否有效,spring中已经提供了这类注解(要手动引入,点这里),比如👇

常用注解

作用
@NotNull 字符串内容不能为空
@Max 定义最大值
@Min 定义最小值
@Email 数据必须是邮箱格式
@Future 必须是将来的日期
...

实例中使用代码示例,bean:

@Date
public class User{

    private int id;

    @NotBlank
    private String name;

    @Positive
    private int age;
}

Controller:

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/register")
    public String register(@Validated User user){
        // ... 操作user的数据
    }
}

有时候时候并不能满足我们的要求,比如要求用户的年龄参数只能是18到25之间,传了其他数就认为传参错误。

开始来自定义一个注解👇

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Constraint(validatedBy = AgeValidator.class)
public @interface Youth{

    int value() default 0;

    String message() default "age valid";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

@interface表示新建一个注解,跟class差不多,Youth表示这个注解的名字,使用的时候就是@Youth
@Retention(RetentionPolicy.RUNTIME) 就是说运行时也有效,不懂问题不大。
@Target(ElementType.FIELD) 就是说这个注解只能写在字段上,不懂问题也不大。
@Constraint(validatedBy = CategoryValidator.class) 表示谁来判断被@Youth注解的参数值有效性,我们写了个AgeValidator.class,所以再新建一个AgeValidator类,👇

public class AgeValidator implements ConstraintValidator<Youth, Integer> {

    @Override
    public boolean isValid(Integer age, ConstraintValidatorContext constraintValidatorContext) {
        return age>=18 && age<=25;
    }
}

实现ConstraintValidator接口,并且里面有个isValid的方法,这个方法返回true表示被@Youth注解的字段是有效的,否则无效。
ConstraintValidator的泛型参数,第一个要为其提供判断的注解,这里就是Youth,第二个表示你这个注解标在哪种数据类型上,我们这里注解在年龄上,所以是Integer。


可以了,现在可以使用了。

@Date
public class User{

    private int id;

    @NotBlank
    private String name;

    @Youth
    private int age;
}

这时候前端传递的age如果不是在18和25中间,那么就会报错。


什么,非对象类型参数也想要这种注解?像下面这样?

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/detail/{id}")
    public String detail(@PathVariable Integer id){
        // ... 操作user的数据
    }

    @GetMapping("/search")
    public String search(Integer age){
        // ... 操作user的数据
    }
}

此时注解需要加载参数上,则需要修改注解@Youth

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER}) //只要修改这里 修改成这样
@Constraint(validatedBy = AgeValidator.class)
public @interface Youth{

    int value() default 0;

    String message() default "age valid";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

多了个ElementType.PARAMETER表示这个注解也可以加在参数上。
修改完成,继续使用👇

@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/search")
    public String search(@Youth Integer age){
        // ... 操作user的数据
    }

    @GetMapping("/detail/{id}")
    public String detail(@PathVariable @Youth Integer id){
        // ... 操作user的数据
    }
}

不出意外的话,是没有效果的,因为还要加上

@Validated    // 添加这个
@RestController
@RequestMapping("/user")
public class UserController {
    // ...
}

这下就好了,🤭

相关文章

网友评论

      本文标题:Spring之自定义注解

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