SpringBoot中同时使用@RequestParam和@RequestBody & 添加枚举校验注解

项目中需要用到url后面拼接参数,post中批量传参的场景

所以就有了如下的实现方案:

@RequestParam和@RequestBody两个注解同时使用,看到网上有人说尽量不要这么使用,我还没去探究为什么。

@Data
public class Request {
    /**
     * 纬度
     */
    @NotNull(message = "latitude不能为空")
    private Double latitude;

    /**
     * 经度
     */
    @NotNull(message = "longitude不能为空")
    private Double longitude;

    /**
     * 区分每个坐标的id
     */
    @NotNull(message = "coordinateId不能为空")
    private String coordinateId;

    /**
     * 坐标体系,支持wgs84ll、gcj02ll,默认wgs84ll
     */
    @EnumValid(target = CoordinateChannel.class, message = "仅支持wgs84ll、gcj02ll坐标体系")
    private String coordinateType = "wgs84ll";
}

 枚举类:

public enum CoordinateChannel {
    WGS84LL(1, "wgs84ll"),
    GCJ02LL(2, "gcj02ll");

    private String value;
    private Integer index;

    CoordinateChannel(Integer index, String value) {
        this.index = index;
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public Integer getIndex() {
        return index;
    }

    public void setIndex(Integer index) {
        this.index = index;
    }

    @Override
    public String toString() {
        return value;
    }
}
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {EnumValidator.class})
public @interface EnumValid {

    String message() default "";

    // 作用参考@Validated和@Valid的区别
    Class[] groups() default {};

    Class[] payload() default {};

    /**
     * 目标枚举类
     */
    Class target() default Class.class;

    /**
     * 是否忽略空值
     */
    boolean ignoreEmpty() default true;
}
public class EnumValidator implements ConstraintValidator {
    // 枚举校验注解
    private EnumValid annotation;

    @Override
    public void initialize(EnumValid constraintAnnotation) {
        annotation = constraintAnnotation;
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        boolean result = false;
        Class cls = annotation.target();
        boolean ignoreEmpty = annotation.ignoreEmpty();
        // target为枚举,并且value有值,或者不忽视空值,才进行校验
        if (cls.isEnum() && (value != null || !ignoreEmpty)) {
            Object[] objects = cls.getEnumConstants();
            for (Object obj : objects) {
                // 使用此注解的枚举类需要重写toString方法,改为需要验证的值
                if (obj.toString().equals(value)) {
                    result = true;
                    break;
                }
            }
        } else {
            result = true;
        }
        return result;
    }
}

使用@RequestParam和@RequestBody注解

    @RequestMapping("/test")
    public Map fenceBatchExit(@RequestParam(value = "tid") String tid,
                              @RequestParam(value = "code") String code,
                              @Valid @RequestBody List requests) {
        int size = requests.size();
        // 加一个size大小的限定

        Map map = new HashMap();
        List searchData = null;
        for (Request  request: requests) {
            // 逻辑处理            

            map.put(request.getId(), searchData);
        }
        return map;
    }

 注意全局捕获ConstraintViolationException异常:捕获上面注解方法中传参错误的情况

注意:下面的代码只是一个模板示例

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public ResultModel exceptionHandler(HttpServletRequest request, Exception e) {
        ResultModel resultModel = new ResultModel();
        log.error("GlobalExceptionHandler exceptionHandler e->{}", e.getMessage());
        try {
            if (e instanceof ConstraintViolationException){
                resultModel.setMsg(e.getMessage());
                resultModel.setRet(******);
            } else {
                resultModel.setMsg(*****);
                resultModel.setRet(*****);
            }
        } catch (Exception ex) {
            logger.error("GlobalExceptionHandler exceptionHandler ex{}", ex);
        } finally {
            MDC.clear();
        }
        return resultModel;
    }
}

下面请求方法新手可看,大佬可以移步了:

SpringBoot中同时使用@RequestParam和@RequestBody & 添加枚举校验注解_第1张图片

你可能感兴趣的:(Java学习记录,spring,boot)