springboot引入Cron实现cron表达式校验解析

一、前言
在开发中,需要检验cron表达式的合法性以及获取执行时间。在CronUtils中实现了这些功能。

二、引入maven依赖

<dependency>
            <groupId>com.cronutils</groupId>
            <artifactId>cron-utils</artifactId>
            <version>9.1.5</version>
        </dependency>

        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.2</version>
        </dependency>

二、建工具类 CronUtils

import com.cronutils.descriptor.CronDescriptor;
import com.cronutils.model.Cron;
import com.cronutils.model.CronType;
import com.cronutils.model.definition.CronDefinition;
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.model.time.ExecutionTime;
import com.cronutils.parser.CronParser;

public class CronUtils {
	
	public static void main(String[] args) {
		String expression = "0 0 0 ? 5 2#1";
		expression = "0 0 12 7 * ?";

		//格式校验
		boolean b = checkCronValid(expression);
		System.out.println(b);

		if (b) {
			//解释cron表达式
			String s = describeCron(expression);
			System.out.println(s);

			//获取下次运行时间
			List<Date> nextExecTime = null;
			try {
				nextExecTime = getNextExecTime(expression, 1);
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			Optional.of(nextExecTime).ifPresent( n -> n.stream().forEach(d -> {
				System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d));
			}));
			System.err.println(parseCronToExeTime(expression));
		}
	}
	/**
     * 解释cron表达式
     */
    public static String describeCron(String expression) {
        CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
        CronParser parser = new CronParser(cronDefinition);
        Cron cron = parser.parse(expression);
        //设置语言
        CronDescriptor descriptor = CronDescriptor.instance(Locale.CHINESE);
        return descriptor.describe(cron);
    }
    /**
     * 解析cron转化为执行时间
     * @param expressiion
     * @return
     */
    public static String parseCronToExeTime(String expression) {
    	 CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.SPRING);
         CronParser parser = new CronParser(cronDefinition);
         Cron cron = parser.parse(expression);
         ExecutionTime exeTime=ExecutionTime.forCron(cron);
         ZonedDateTime now = ZonedDateTime.now();
         //根据当前时间获取下次执行时间
         ZonedDateTime next = exeTime.nextExecution(now).get();
         DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
         
         return next.format(format);
    }
    /**
     * @param cronExpression cron表达式 
     * @param numTimes       下一(几)次运行的时间
     * @return
     */
    public static List<Date> getNextExecTime(String cronExpression, Integer numTimes) throws ParseException {
        CronTriggerImpl cronTriggerImpl = new CronTriggerImpl();
        cronTriggerImpl.setCronExpression(cronExpression);
        // 这个是重点,一行代码搞定
        return TriggerUtils.computeFireTimes(cronTriggerImpl, null, numTimes);
    }
    /**
     * 检查cron表达式的合法性
     *
     * @param cron cron exp
     * @return true if valid
     */
    public static boolean checkCronValid(String cron) {
        try {          
            return CronExpression.isValidExpression(cron);
        } catch (Exception e) {
            System.out.println(String.format("cron=%s not valid", cron));
            return false;
        }
    }
}

三、具体使用
在实际接口中,我们也会使用到,比如我们新建了个调度组,调度执行任务,那么我们可能就需要解析cron的表达式,得到下次执行的时间。

首先新建调度组entity

/**
 * 调度组
 * @author Lenovo
 *
 */
public class SchedulerGroup {
	private Integer groupId;
	
	private String groupName;
	
	private String cronExpression;
	
	private String execTime;
}

接下来编写相关业务代码

import java.util.List;

import entity.SchedulerGroup;
import utils.CronUtils;

@Service
public class SchedulerGroupService {
	@Autowire
	private SchedulerGroupMapper schedulerGroupMapper;
	public List<SchedulerGroup> querySchedulerGroup() {
		List<SchedulerGroup> groupList = schedulerGroupMapper.selectList();
		
		for(SchedulerGroup group : groupList) {
			String execTime = CronUtils.parseCronToExeTime(group.getCronExpression());
			group.setExecTime(execTime);
		}
		return groupList;
		
	}
}

上面是查询调度组列表,需展示下次调度执行时间。

当然,我们在创建的时候,也需校验cron表达式是否合法,调用工具类中的checkCronValid() 方法校验即可,一般不建议用正则表达式匹配验证cron表达式,一是匹配规则太复杂几乎没法修改,二是容易出错,所以强烈建议你使用CronExpression包进行验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜空下的星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值