SpringBoot接口参数校验(jakarta.validation.constraints)

一.引入pom

        <!-- validation -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

二.定义实体

注意:存在实体嵌套的时候要在对象类型属性加@Valid注解,否则嵌套实体定义的校验注解不生效

1.定义DTO

package com.example.redission.entity;
import com.example.redission.annotation.LegalEnum;
import com.example.redission.enums.ScopeEnum;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;

/**
 * @version 1.0
 * @date 2024/5/13
 * @description
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class WelcomeDto {
    private String id;

    @NotBlank(message = "标题不能为空")
    private String name;

    @NotBlank(message = "范围不能为空")
    @LegalEnum(value = ScopeEnum.class, message = "范围枚举值不合法")
    private String scope;

    @Valid
    @Size(max = 5, message = "User不能超过5个")
    private List<User> userList;
}

2.User

package com.example.redission.entity;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * @author  土
 * @version 1.0
 * @date 2024/5/15
 * @description
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
    @NotBlank(message = "标题不能为空")
    private String name;
    @Valid
    @Size(max = 5, message = "Address不能超过5个")
    @NotNull
    private List<Address> addressList;
}

3.Address

package com.example.redission.entity;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author OP0345
 * @version 1.0
 * @date 2024/5/15
 * @description  
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Address {
    @NotBlank(message = "省份不能为空")
    private String province;
}

三.定义枚举类

package com.example.redission.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.stream.Stream;

@Getter
@AllArgsConstructor
public enum ScopeEnum {
    ALL_USER("all", "全部企微号"),
    TAG("tag", "指定层级"),
    SOME_USER("some", "指定企微号");

    private final String type;
    private final String desc;
    public static ScopeEnum findBy(String value) {
        return Stream.of(ScopeEnum.values())
                .filter(item -> item.getType().equals(value))
                .findFirst()
                .orElse(null);
    }
}

四.自定义枚举参数校验注解

package com.example.redission.annotation;


import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;

/**
 * 枚举类型校验
 *
 * @author :
 */
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = LegalEnum.EnumValidator.class)
public @interface LegalEnum {

    String message() default "无效的枚举值";

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

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

    Class<? extends Enum<?>> value();

    class EnumValidator implements ConstraintValidator<LegalEnum, Object> {

        private Class enumClass;

        @Override
        public void initialize(LegalEnum constraintAnnotation) {
            this.enumClass = constraintAnnotation.value();
        }

        @Override
        public boolean isValid(Object value, ConstraintValidatorContext context) {
            if (value == null) {
                return false;
            }
            if (!enumClass.isEnum()) {
                throw new IllegalArgumentException(enumClass.getSimpleName() + " is not an enum type");
            }
            try {
            	//基于type属性
                Field field = enumClass.getDeclaredField("type");
                field.setAccessible(true);
                Object[] enumConstants = enumClass.getEnumConstants();
                for (Object enumConstant : enumConstants) {
                    Object fieldValue = field.get(enumConstant);
                    if (fieldValue != null && fieldValue.equals(value)) {
                        return true;
                    }
                }
                return false;
            } catch (NoSuchFieldException | IllegalAccessException e) {
                throw new RuntimeException("Error validating enum", e);
            }
        }
    }

}

五.controller接口验证

package com.example.redission.controller;

import com.example.redission.annotation.RateLimit;
import com.example.redission.entity.WelcomeDto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * @author 土
 * @version 1.0
 * @description controller
 */
@RestController
@RequestMapping("/hello")
@Slf4j
@RequiredArgsConstructor
@Validated
public class ApiController {
    //    @RedisLock(key = "'lock_' + #str")
    @GetMapping(value = "say", produces = MediaType.APPLICATION_JSON_VALUE)
    public String send(@RequestParam(name = "str") @NotNull @NotBlank(message = "str必输") String str) {
        return str;
    }

    @PostMapping(value = "addOne", produces = MediaType.APPLICATION_JSON_VALUE)
    public String addOne(@Validated @RequestBody WelcomeDto dto) {
        System.out.println("进来了");
        return dto.getName();
    }
}

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值