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


写接口,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集合
         */
        @Override
        public void initialize(ListValue constraintAnnotation) {
   
            String[] values = constraintAnnotation.valueList();  
            set.addAll(Arrays.asList(values));
        }

        /**
         * 校验逻辑,返回false即值不存在,代表超出范围
         */
        @Override
        public 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);

    @JsonCreator
    public static OrderFieldEnum unSerializer(String value){
   
    	//把以value为key,以枚举对象为value,存进map
        if(map.isEmpty()){
   
            for (OrderFieldEnum fieldEnum : OrderFieldEnum.values()) {
   
                map.put(fieldEnum.value,fieldEnum);
            }
        }
        //map中找不到就是超出范围
        if(!map.containsKey(value)){
   
            throw new RuntimeException("超出范围");
        }
        return map.get(value);
    }

    @JsonValue
    public String getValue(){
   
        return this.value;   
    }


}

此时Dto:

public class Dto {
   
	
	OrderFieldEnum orderField;
	
}

4、其余校验实现思路3.0

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

在这里插入图片描述

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

@Service
public Service implements IService{
   

	@Override
	public doSome(Dto dto){
   
		FieldEnum.checkCodeExist(dto.getField);
		//....
	}
}

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

相关推荐

  1. springboot 注解+AOP实现接口方法出入打印

    2024-01-18 14:14:08       68 阅读
  2. vue实现父子

    2024-01-18 14:14:08       60 阅读
  3. shell脚本调用http接口

    2024-01-18 14:14:08       23 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-18 14:14:08       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-18 14:14:08       106 阅读
  3. 在Django里面运行非项目文件

    2024-01-18 14:14:08       87 阅读
  4. Python语言-面向对象

    2024-01-18 14:14:08       96 阅读

热门阅读

  1. 题目 1761: 学习ASCII码

    2024-01-18 14:14:08       57 阅读
  2. Centos下,使用NFS实现目录共享/网络驱动器

    2024-01-18 14:14:08       48 阅读
  3. ElasticSearch 学习、实践笔记

    2024-01-18 14:14:08       49 阅读
  4. 《微信小程序开发从入门到实战》学习八十五

    2024-01-18 14:14:08       47 阅读
  5. SpringBoot整合Minio

    2024-01-18 14:14:08       46 阅读
  6. 【项目搭建一】SpringBoot引入logback

    2024-01-18 14:14:08       49 阅读