zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Spring学习笔记(二十五)——springboot定时任务和Gson、Date、进制等工具的使用

SpringSpringBoot工具笔记学习 使用 任务 定时
2023-06-13 09:11:07 时间

SpringBoot定时任务

在项目开发过程中,我们经常需要执行具有周期性的任务。通过定时任务可以很好的帮助我们实现。 spring项目启动后想对一些数据做同步,一些表数据要不定时统计,一些业务报表的汇总和生成,大量数据导入后台处理,一般都是用定时任务去处理,对于太占资源的任务需要后台处理,越复杂的系统定时任务也越多,需要监控的东西也很多。 而在springBoot提供了简单的定时任务支持,由于Spring Schedule包含在spring-boot-starter基础模块中了,所有不需要增加额外的依赖。

操作步骤

  1. 初始化项目之后,我们需要在spring boot的入口类Application.java中,允许支持schedule
@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  1. 然后,新建一个执行类Jobs.java
@Component
public class Jobs {
    public final static long ONE_Minute =  60 * 1000;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Scheduled(fixedDelay=ONE_Minute)
    public void fixedDelayJob(){
        System.out.println(sdf.format(new Date()) +" >>fixedDelay执行....");
    }

    @Scheduled(fixedRate=ONE_Minute)
    public void fixedRateJob(){
        System.out.println(sdf.format(new Date())+" >>fixedRate执行....");
    }

    @Scheduled(cron="0 15 7 * * ?")
    public void cronJob(){
        System.out.println(sdf.format(new Date())+" >>cron执行....");
    }
}

@Scheduled参数说明:

  1. fixedDelay和fixedRate是最简单的2种方式,多少分钟执行一次,单位是毫秒,所以1分钟就是60秒×1000。
  2. 他们的区别在于,fixedRate就是每多次分钟一次,不论你业务执行花费了多少时间。我都是1分钟执行1次,而fixedDelay是当任务执行完毕后1分钟在执行。所以根据实际业务不同,我们会选择不同的方式。 而还有一类定时任务,比如是每天的7点15分执行,那么我们就需要用另外一种方式:cron表达式
  3. cron表达式,有专门的语法(Linux中的定时任务也是使用cron),而且感觉有点绕人,不过简单来说,大家记住一些常用的用法即可,特殊的语法可以单独去查。 cron一共有7位,但是最后一位是年,可以留空,所以我们可以写6位:
* 第一位,表示秒,取值0-59
* 第二位,表示分,取值0-59
* 第三位,表示小时,取值0-23
* 第四位,日期天/日,取值1-31
* 第五位,日期月份,取值1-12
* 第六位,星期,取值1-7,星期一,星期二...,注:不是第1周,第二周的意思
          另外:1表示星期天,2表示星期一。
* 第7为,年份,可以留空,取值1970-2099

cron中,还有一些特殊的符号,含义如下:

(*)星号:可以理解为每的意思,每秒,每分,每天,每月,每年...
(?)问号:问号只能出现在日期和星期这两个位置,表示这个位置的值不确定,每天3点执行,所以第六位星期的位置,我们是不需要关注的,就是不确定的值。同时:日期和星期是两个相互排斥的元素,通过问号来表明不指定值。比如,1月10日,比如是星期1,如果在星期的位置是另指定星期二,就前后冲突矛盾了。
(-)减号:表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12
(,)逗号:表达一个列表值,如在星期字段中使用“1,2,4”,则表示星期一,星期二,星期四
(/)斜杠:如:x/y,x是开始值,y是步长,比如在第一位(秒) 0/15就是,从0秒开始,每15秒,最后就是0,15,30,45,60    另:*/y,等同于0/y

下面列举几个例子来验证:

0 0 3 * * ?     每天3点执行
0 5 3 * * ?     每天3点5分执行
0 5 3 ? * *     每天3点5分执行,与上面作用相同
0 5/10 3 * * ?  每天3点的 5分,15分,25分,35分,45分,55分这几个时间点执行
0 10 3 ? * 1    每周星期天,3点10分 执行,注:1表示星期天    
0 10 3 ? * 1#3  每个月的第三个星期,星期天 执行,#号只能出现在星期的位置

SpringBoot中发送请求和Gson使用

java中发送请求:

参考一:https://www.cnblogs.com/leeego-123/p/12144525.html 参考二(我之前的博客):http://qkongtao.cn/?p=569#i

Gson的使用

我们来测试一个比较复杂的接口数据 使用高德地图提供的天气预报接口服务: 官方文档:https://lbs.amap.com/api/webservice/guide/api/weatherinfo 具体申请key和怎么使用该天气接口可以参看官方文档来实现 申请完接口之后,使用如下: https://restapi.amap.com/v3/weather/weatherInfo?key=你的key&extensions=all&city=330100 是get请求,可以直接使用浏览器访问: 结果如下

里面的数据又杂又多,在Java后端返回回来的是json字符串,无法像js那样直接转换为json对象直接访问。这个时候我们就可以用到Google提供的Gson工具来很方便的处理这些数据。 比如我们处理日期为 2021-07-22 的天气:

Gson使用步骤

  1. 导入pom.xml依赖
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.3</version>
        </dependency>
  1. 新建 GetEmailInfosUtil.java 工具类
/**
 * @author tao
 * @date 2021-07-21 22:06
 * 概要:
 */
public class GetEmailInfosUtil {

    /*获取天气*/
    public static String getWeather() {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("https://restapi.amap.com/v3/weather/weatherInfo?key=你的KEY&extensions=all&city=330100", String.class);
        //城市名,天气现象(白天,晚上),实时气温白天,晚上,风向描述,风力级别,数据发布的时间
        String city, dayweather, nightweather, nighttemp, daytemp, winddirection, windpower, reporttime, forecasts;
        String result = responseEntity.getBody();
        JsonParser jp = new JsonParser();
        //将json字符串转化成json对象
        JsonObject resultJo = jp.parse(result).getAsJsonObject();
        JsonElement jsonElement = resultJo.get("forecasts").getAsJsonArray().get(0);
        forecasts = jsonElement.toString();
        //System.out.println("forecasts=" + forecasts);
        JsonObject forecastsJo = jp.parse(forecasts).getAsJsonObject();

        JsonElement jsonElementCasts = forecastsJo.get("casts").getAsJsonArray().get(0);
        JsonObject castsJo = jp.parse(jsonElementCasts.toString()).getAsJsonObject();
        //获取对应的值
        city = forecastsJo.get("city").getAsString();
        reporttime = forecastsJo.get("reporttime").getAsString();
        dayweather = castsJo.get("dayweather").getAsString();
        nightweather = castsJo.get("nightweather").getAsString();
        nighttemp = castsJo.get("nighttemp").getAsString();
        daytemp = castsJo.get("daytemp").getAsString();
        winddirection = castsJo.get("daywind").getAsString();
        windpower = castsJo.get("daypower").getAsString();
        String weatherText = "小黑天气预报来啦^_^:今日" + city + "天气" + dayweather + (dayweather.equals(nightweather) ? "" : "nightweather") + ";气温是" + nighttemp + "到" + daytemp + "度;风向是" + winddirection + "风,强度是" + windpower + "级。预报时间:" + reporttime + "。";
        return weatherText;
    }
  }
  1. 测试方法
@Test
    void getWeather() {
        String weather = GetEmailInfosUtil.getWeather();
        System.out.println(weather);
    }
  1. 结果如下
  1. Gson的使用说明

* 通过RestTemplate发送请求数据接口获取json的字符串 * new 一个 JsonParser 对象 * jp.parse(result).getAsJsonObject()获取json对象JsonObject * 如果对象中的元素是字符串,则可以直接使用JsonObject对象.get("city").getAsString();获取字符串 * 如果对象中的元素是数组,则可以使用JsonObject对象.get("casts").getAsJsonArray();获取jsonArray数组

Date一些常用的工具方法

1. 获取指定日期加上天数后的日期

/**
     * 指定日期加上天数后的日期
     *
     * @param num     为增加的天数
     * @param newDate 创建时间
     * @return
     * @throws ParseException
     */
    public static String plusDay(int num, String newDate) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date currdate = format.parse(newDate);
        Calendar ca = Calendar.getInstance();
        ca.setTime(currdate);
        ca.add(Calendar.DATE, num);// num为增加的天数,可以改变的
        currdate = ca.getTime();
        String enddate = format.format(currdate);
        return enddate;
    }

2. 字符串的日期格式的计算两个日期相差的天数

 /*
     * 字符串的日期格式的计算
     * @param smdate 时间1
     * @param bdate  时间2
     * @return 时间2 - 时间1
     * @throws ParseException
     */
    public static int daysBetween(String smdate, String bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }

任意进制的转换

使用 new java.math.BigInteger(要转换的数, 源数的进制).toString(要转换成的进制);可以实现实现任意数、任意进制的转换。

以下是两个示例:

1. 10进制转32进制的方法

/**
     * 10进制转32进制的方法
     * num 要转换的数 from源数的进制 to要转换成的进制
     *
     * @param num 10进制(字符串)
     * @return 转换结果的32进制字符串
     */
    public static String change10To32(String num) {
        int from = 10;
        int to = 32;
        return new java.math.BigInteger(num, from).toString(to);
    }

2. 32进制转10进制的方法

 /**
     * 32进制转10进制的方法
     * num 要转换的数 from源数的进制 to要转换成的进制
     *
     * @param num 10进制(字符串)
     * @return 转换结果的10进制字符串
     */
    public static String change32To10(String num) {
        int f = 32;
        int t = 10;
        return new java.math.BigInteger(num, f).toString(t);
    }

测试结果

1.10进制转32进制的方法

2. 32进制转10进制的方法