在项目开发过程中,我们经常需要执行具有周期性的任务。通过定时任务可以很好的帮助我们实现。 spring项目启动后想对一些数据做同步,一些表数据要不定时统计,一些业务报表的汇总和生成,大量数据导入后台处理,一般都是用定时任务去处理,对于太占资源的任务需要后台处理,越复杂的系统定时任务也越多,需要监控的东西也很多。 而在springBoot提供了简单的定时任务支持,由于Spring Schedule包含在spring-boot-starter基础模块中了,所有不需要增加额外的依赖。
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@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执行....");
}
}
* 第一位,表示秒,取值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 每个月的第三个星期,星期天 执行,#号只能出现在星期的位置
参考一:https://www.cnblogs.com/leeego-123/p/12144525.html 参考二(我之前的博客):http://qkongtao.cn/?p=569#i
我们来测试一个比较复杂的接口数据 使用高德地图提供的天气预报接口服务: 官方文档: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 的天气:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.3</version>
</dependency>
/**
* @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;
}
}
@Test
void getWeather() {
String weather = GetEmailInfosUtil.getWeather();
System.out.println(weather);
}
* 通过RestTemplate发送请求数据接口获取json的字符串 * new 一个 JsonParser 对象 * jp.parse(result).getAsJsonObject()获取json对象JsonObject * 如果对象中的元素是字符串,则可以直接使用JsonObject对象.get("city").getAsString();获取字符串 * 如果对象中的元素是数组,则可以使用JsonObject对象.get("casts").getAsJsonArray();获取jsonArray数组
/**
* 指定日期加上天数后的日期
*
* @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;
}
/*
* 字符串的日期格式的计算
* @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(要转换成的进制);可以实现实现任意数、任意进制的转换。
以下是两个示例:
/**
* 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);
}
/**
* 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进制的方法