java自定义注解校验开始时间小于结束时间

java 自定义注解校验时间段

  • 需求
  • 示例代码
    • 1. 自定义注解类
    • 2. 注解的实现类
    • 3. 实体类
    • 4. 测试 Controller
    • 5. postman测试
  • 常见问题及解决方式
    • 1. 请求未进入注解的自定义处理类.
    • 2. 注解处理类中获取不到"开始时间"和"结束时间"参数.
    • 3. 校验错误.

需求

最近做了一个日历模块, 用户可以在模块中新增日程, 需要录入开始时间(scheduleStartTime)和结束时间(scheduleStartTime). 此时需要校验两个参数的大小关系.

示例代码

1. 自定义注解类

package com.ruoyi.common.annotation;
import com.ruoyi.common.validate.DateValidatorClass;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
/**
 * 时间段校验
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//实现类
@Constraint(validatedBy = DateValidatorClass.class)
public @interface TimeInterval {
    // 校验未通过时的返回信息
    String message() default "开始时间不得大于结束时间";
    // 以下两行为固定模板
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

2. 注解的实现类

package com.ruoyi.common.validate;
import com.ruoyi.common.annotation.TimeInterval;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.time.LocalDateTime;

public class DateValidatorClass implements ConstraintValidator<TimeInterval, Object> {
    @Override
    public void initialize(TimeInterval constraintAnnotation) {
    }

    @Override
    public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
        // 需求:非必填字段(null),不传就不做校验
        if (object == null) {
            return true;
        }
        Object startTime = this.getObjectPropertyValue(object, "scheduleStartTime");
        Object endTime = this.getObjectPropertyValue(object, "scheduleEndTime");
        // 起始创建时间、结束创建时间均有值,则结束创建时间不得小于如起始创建时间
        if (null == startTime || null == endTime || !startTime.getClass().equals(endTime.getClass())) {
            return true;
        }
        //long类型对比
        if (startTime instanceof Long && endTime instanceof Long) {
            return (Long) startTime > (Long) endTime;
        }
        //LocalDateTime 类型对比
        if (startTime instanceof LocalDateTime && endTime instanceof LocalDateTime) {
            return ((LocalDateTime) startTime).isBefore((LocalDateTime) endTime);
        }
        return true;
    }


    /**
     * 从Object中获取指定的属性的值
     *
     * @param object
     * @param paramName
     * @return
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    private Object getObjectPropertyValue(Object object, String paramName) {
        Field field = null;
        try {
            field = object.getClass().getDeclaredField(paramName);
            field.setAccessible(true);
            return field.get(object);
        } catch (Exception e) {
            // log.info("===异常信息 e = ", e);
        }
        return null;
    }
}

3. 实体类

package com.ruoyi.web.controller.demo.domain;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.TimeInterval;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
@TimeInterval
public class TimeIntervalModel {
    /**
     * 开始时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime scheduleStartTime;
    /**
     * 结束时间
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime scheduleEndTime;

    public LocalDateTime getScheduleStartTime() {
        return scheduleStartTime;
    }

    public void setScheduleStartTime(LocalDateTime scheduleStartTime) {
        this.scheduleStartTime = scheduleStartTime;
    }

    public LocalDateTime getScheduleEndTime() {
        return scheduleEndTime;
    }

    public void setScheduleEndTime(LocalDateTime scheduleEndTime) {
        this.scheduleEndTime = scheduleEndTime;
    }

4. 测试 Controller

package com.ruoyi.web.controller.demo.controller;
import com.ruoyi.common.annotation.TimeInterval;
import com.ruoyi.web.controller.demo.domain.TimeIntervalModel;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/demo")
public class DemoController {
    @PostMapping("interval")
    public String testInteval(@Validated @RequestBody TimeIntervalModel model) {
        System.out.println("model. = " + model.getScheduleEndTime());
        return "success";
    }
}

5. postman测试

{
    "msg": "开始时间不得大于结束时间",
    "code": 500
}

常见问题及解决方式

1. 请求未进入注解的自定义处理类.

	检查controller中方法是否添加  @Validated 注解

2. 注解处理类中获取不到"开始时间"和"结束时间"参数.

 检查 添加的参数名 是否和 实体类中的参数名一致. 

3. 校验错误.

检查实体类中定义的参数类型, 和处理类中"isValid"是否一致. 
	例如:  private  DateTime scheduleStartTime;
	那么在 isValid方法中 需要对 DateTime 类型的数据进行处理. 

你可能感兴趣的:(java,开发语言,spring)