ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

注解实现校验接口传参是否超出取值范围

2026/8/5 19:18:02 拓冰建站 浏览量
注解实现校验接口传参是否超出取值范围

文章目录

  • 1、定义注解
  • 2、使用注解
  • 3、其余校验实现思路2.0
  • 4、其余校验实现思路3.0

写接口,Dto里很多字段要检验传参范围,自定义个注解来校验。

1、定义注解

注解定义代码:

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;@Target(ElementType.FIELD)
@Constraint(validatedBy = ListValue.ValidIfInRange.class)   //借助@Constraint注解实现自定义校验逻辑,validatedBy属性是数组类型,可同时定义多种校验逻辑
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ListValue {String message() default "The parameters are out of range, please check it.";  //超出取值范围后的抛错信息String[] valueList() default {};   //要检验的取值范围Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};class ValidIfInRange implements ConstraintValidator<ListValue, String> {private final Set<String> set = new HashSet<>();/*** 初始化逻辑,把取值范围存入Collection集合*/@Overridepublic void initialize(ListValue constraintAnnotation) {String[] values = constraintAnnotation.valueList();  set.addAll(Arrays.asList(values));}/*** 校验逻辑,返回false即值不存在,代表超出范围*/@Overridepublic boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {return set.contains(s);}}
}

实现思路是使用JSR303校验框架的@Constraint注解,实现ConstraintValidator接口,定义初始化和参数校验逻辑。

<!--PS: JSR303校验框架依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2、使用注解

@PostMapping("/test")
public void doSome3(@Validated @RequestBody Dto dto){}
public class Dto {@ListValue(valueList = {"createTime", "updateTime"}, message ="排序字段超出取值范围")String orderField;}	

调用下:

在这里插入图片描述
在这里插入图片描述

3、其余校验实现思路2.0

借用 @JsonCreator 注解,反序列化前端传参成一个枚举对象时,进行校验。

@AllArgsConstructor
@Getter
public enum OrderFieldEnum {CREATE_TIME("createTime","create_time"),USER_NAME("userName","user_name");private final String value;private final String field;private static final Map<String,OrderFieldEnum> map = new HashMap<>(3);@JsonCreatorpublic static OrderFieldEnum unSerializer(String value){//把以value为key,以枚举对象为value,存进mapif(map.isEmpty()){for (OrderFieldEnum fieldEnum : OrderFieldEnum.values()) {map.put(fieldEnum.value,fieldEnum);}}//map中找不到就是超出范围if(!map.containsKey(value)){throw new RuntimeException("超出范围");}return map.get(value);}@JsonValuepublic String getValue(){return this.value;   }}

此时Dto:

public class Dto {OrderFieldEnum orderField;}

4、其余校验实现思路3.0

这个就比较原始了,直接枚举类定义静态代码块完成取值范围初始化 + 一个静态方法完成校验:

在这里插入图片描述

这么实现的话,Service层就得调用方法校验下:

@Service
public Service implements IService{@Overridepublic doSome(Dto dto){FieldEnum.checkCodeExist(dto.getField);//....}
}

其余优秀帖子备份:https://juejin.cn/post/7009190724214194207