JAVA 定时任务Corn的对象设计和corn字符串转换

本文详细介绍了在JAVA中如何设计定时任务Corn的相关对象,并提供了从Corn字符串到对象的转换工具类,涵盖了主对象、子对象的定义及转换测试的过程。

1.定义主对象

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ApiModel("定时任务corn对象")
public class TimingCornVo {

    @ApiModelProperty(value = "corn字符串")
    String corn;

    @ApiModelProperty(value = "corn转换后数据集合")
    List<TimingCornSubVo> subVoList;
}

2.定义子对象,用于存放corn的每个部分数据

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ArrayUtils;


@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ApiModel("定时任务corn子对象")
public class TimingCornSubVo {

    @ApiModelProperty(value = "数据类型[0:秒,1:分,2时,3:日,4:月,5:周,6:年]")
    Integer type;

    @ApiModelProperty(value = "使用类型[0:不指定,1:每单位执行,2:周期执行内单位频率执行,3:指定开始时间和频率,4:指定时间执行,5最后一个(日和周,月中最后一个月或月中最后的星期)]")
    Integer useType;

    @ApiModelProperty(value = "执行时间数据[useType2:两个数据,表示x-y,useType3:任意个合法范围内数值],useType4:两个数据,表示x/y")
    Integer[] data;


    /**
     * 参数校验
     * 在工具类中对顺序进行了排序,因此此处不校验大小问题
     */
    public void checkParam() throws Exception {
        if (null==type||type<0||type>6){
            throw new Exception("类型取值不合法");
        }
        if (null==useType||useType<0||useType>5){
            throw new Exception("使用类型取值不合法");
        }
        if (useType == 0){
            if (type<3){
                throw new Exception("秒,分,时使用类型不能为不指定");
            }
        }else if (useType == 2){
            if (ArrayUtils.isEmpty(data)||data.length!=2){
                throw new Exception("周期执行类型数据必须为两个");
            }
        }else if (useType == 3){
            if (ArrayUtils.isEmpty(data)||data.length!=2){
                throw new Exception("指定开始和频率类型数据必须为两个");
            }
        }else if (useType == 4){
            if (ArrayUtils.isEmpty(data)&&type!=6){
                throw new Exception("指定时间类型数据不能为空");
            }
            for (Integer datum : data) {
                switch (type){
                    case 0:
                        if (datum<0||datum>59){
                            throw new Exception("秒只能为1-60");
                        }
                        break;
                    case 1:
                        if (datum<0||datum>59){
                            throw new Exception("分只能为1-60");
                        }
                        break;
                    case 2:
                        if (datum<0||datum>23){
                            throw new Exception("时只能为1-24");
                        }
                        break;
                    case 3:
                        if (datum<1||datum>31){
                            throw new Exception("日只能为1-31");
                        }
                        break;
                    case 4:
                        if (datum<1||datum>12){
                            throw new Exception("月只能为1-12");
                        }
                        break;
                    case 5:
                        if (datum<1||datum>7){
                            throw new Exception("周只能为1-7");
                        }
                        break;
                    case 6:
                        if (datum<1970||datum>2099){
                            throw new Exception("年只能为1970-2099");
                        }
                        break;
                }
            }
        }else if (useType == 4){
            if (type!=3||type!=5){
                throw new Exception("最后一个使用类型仅日和周可以使用");
            }else if (type==5){
                if (ArrayUtils.isEmpty(data)||data.length!=1){
                    throw new Exception("最后一个使用类型必须指定一个星期数值");
                }
            }
        }

    }

}

3.创建对象和corn字符串转换工具类

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.regex.Pattern;


/**
 * corn转换工具类
 */
public class TimingCornUtil {
    //corn正则校验
    private static final String regEx = "^\\s*($|#|\\w+\\s*=|(\\?|\\*|(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?(?:,(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?)*)\\s+(\\?|\\*|(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?(?:,(?:[0-5]?\\d)(?:(?:-|\\/|\\,)(?:[0-5]?\\d))?)*)\\s+(\\?|\\*|(?:[01]?\\d|2[0-3])(?:(?:-|\\/|\\,)(?:[01]?\\d|2[0-3]))?(?:,(?:[01]?\\d|2[0-3])(?:(?:-|\\/|\\,)(?:[01]?\\d|2[0-3]))?)*)\\s+(\\?|\\*|(?:0?[1-9]|[12]\\d|3[01])(?:(?:-|\\/|\\,)(?:0?[1-9]|[12]\\d|3[01]))?(?:,(?:0?[1-9]|[12]\\d|3[01])(?:(?:-|\\/|\\,)(?:0?[1-9]|[12]\\d|3[01]))?)*)\\s+(\\?|\\*|(?:[1-9]|1[012])(?:(?:-|\\/|\\,)(?:[1-9]|1[012]))?(?:L|W)?(?:,(?:[1-9]|1[012])(?:(?:-|\\/|\\,)(?:[1-9]|1[012]))?(?:L|W)?)*|\\?|\\*|(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?(?:,(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(?:(?:-)(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)*)\\s+(\\?|\\*|(?:[0-6])(?:(?:-|\\/|\\,|#)(?:[0-6]))?(?:L)?(?:,(?:[0-6])(?:(?:-|\\/|\\,|#)(?:[0-6]))?(?:L)?)*|\\?|\\*|(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?(?:,(?:MON|TUE|WED|THU|FRI|SAT|SUN)(?:(?:-)(?:MON|TUE|WED|THU|FRI|SAT|SUN))?)*)(|\\s)+(\\?|\\*|(?:|\\d{4})(?:(?:-|\\/|\\,)(?:|\\d{4}))?(?:,(?:|\\d{4})(?:(?:-|\\/|\\,)(?:|\\d{4}))?)*))$";
    private static final Pattern cornPattern = Pattern.compile(regEx);

    /**
     * obj转corn字符串
     * @param cornVo
     * @return
     * @throws Exception
     */
    public static String objToStr(TimingCornVo cornVo) throws Exception {
        List<TimingCornSubVo> subVoList = cornVo.getSubVoList();
        //年数据可以没有,因此子数据集合为6-7个
        if (CollectionUtils.isEmpty(subVoList)||subVoList.size()<6||subVoList.size()>7){
            throw new Exception("数据错误");
        }
        //对数据按照日期类型排序
        subVoList.sort(Comparator.comparing(TimingCornSubVo::getType));
        //使用空格对字符串进行拼接
        StringJoiner cornStrJoiner = new StringJoiner(" ");
        for (int i = 0; i < subVoList.size(); i++) {
            TimingCornSubVo subVo = subVoList.get(i);
            //校验参数
            subVo.checkParam();
            Integer[] data = subVo.getData();
            if (subVo.getType()!=i){
                throw new Exception("数据日期类型错误,必须含有秒,分,时,日,月,周这6种数据");
            }
            if (ArrayUtils.isNotEmpty(data)){
                //对数据进行排序,防止出现填反的情况
                Arrays.sort(data);
            }
            //i-type-0:秒,1:分,2时,3:日,4:月,5:周,6:年
            //useType0:不指定,1:每单位执行,2:周期执行内单位频率执行,3:指定开始时间和频率,4:指定时间执行,5最后一个
            switch (subVo.getUseType()){
                case 0:
                    cornStrJoiner.add("?");
                    break;
                case 1:
                    cornStrJoiner.add("*");
                    break;
                case 2:
                    cornStrJoiner.add(data[0]+"-"+data[1]);
                    break;
                case 3:
                    cornStrJoiner.add(data[0]+"/"+data[1]);
                    break;
                case 4:
                    StringJoiner dataJoiner = new StringJoiner(",");
                    for (Integer datum : data) {
                        dataJoiner.add(datum+"");
                    }
                    cornStrJoiner.add(dataJoiner.toString());
                    break;
                case 5:
                    if (i==3){
                        cornStrJoiner.add("L");
                    }else {
                        cornStrJoiner.add(data[0]+"L");
                    }
                    break;

            }
        }
        cornVo.setCorn(cornStrJoiner.toString());
        return cornStrJoiner.toString();

    }


    /**
     * corn字符串转obj
     * @param corn
     * @return
     */
    public static TimingCornVo strToObj(String corn) throws Exception {
        if (StringUtils.isEmpty(corn)){
            throw new Exception("corn表达式为空");
        }
        if (!cornPattern.matcher(corn).matches()){
            throw new Exception("corn表达式格式有误");
        }
        String[] data = corn.split(" ");
        List<TimingCornSubVo> subVoList = new ArrayList<>();
        TimingCornVo result = TimingCornVo.builder()
                .corn(corn)
                .subVoList(subVoList).build();
        for (int i = 0; i < data.length; i++) {
            TimingCornSubVo subVo = TimingCornSubVo.builder()
                    .type(i).build();
            String subStr = data[i];
            //useType0:不指定,1:每单位执行,2:周期执行内单位频率执行,3:指定开始时间和频率,4:指定时间执行,5最后一个
            if ("?".equals(subStr)){
                subVo.setUseType(0);
            }else if ("*".equals(subStr)){
                subVo.setUseType(1);
            }else if (subStr.contains("-")){
                subVo.setUseType(2);
                String[] split = subStr.split("-");
                Integer[] subStrSplitData = new Integer[2];
                subStrSplitData[0] = Integer.parseInt(split[0]);
                subStrSplitData[1] = Integer.parseInt(split[1]);
                subVo.setData(subStrSplitData);
            }else if (subStr.contains("/")){
                subVo.setUseType(3);
                String[] split = subStr.split("/");
                Integer[] subStrSplitData = new Integer[2];
                subStrSplitData[0] = Integer.parseInt(split[0]);
                subStrSplitData[1] = Integer.parseInt(split[1]);
                subVo.setData(subStrSplitData);
            }else if (subStr.contains("L")){
                subVo.setUseType(5);
                if (i==5){
                    Integer[] subStrSplitData = new Integer[1];
                    subStrSplitData[0] = Integer.parseInt(subStr.replace("L",""));
                    subVo.setData(subStrSplitData);
                }
            }else{
                subVo.setUseType(4);
                String[] split = subStr.split(",");
                Integer[] subStrSplitData = new Integer[split.length];
                for (int i1 = 0; i1 < subStrSplitData.length; i1++) {
                    subStrSplitData[i1] = Integer.parseInt(split[i1]);
                }
                subVo.setData(subStrSplitData);
            }
            subVoList.add(subVo);
        }
        return result;
    }
}

4.测试

    public static void main(String[] args) throws Exception {
        String corn = "0 15,17,19 10/5 ? * 6L 2002-2005";
        TimingCornVo timingCornVo = TimingCornUtil.strToObj(corn);
        for (TimingCornSubVo subVo : timingCornVo.getSubVoList()) {
            System.out.println(subVo.getType()+"|"+subVo.getUseType()+"|"+ArrayUtils.toString(subVo.getData()));
        }
        System.out.println(corn);
        System.out.println(TimingCornUtil.objToStr(timingCornVo));
        //测试结果可以看出corn字符串转换对象符合预期并且可以正确转回corn字符串
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值