目录
SpringBoot定时任务
在项目开发过程中,我们经常需要执行具有周期性的任务。通过定时任务可以很好的帮助我们实现。
spring项目启动后想对一些数据做同步,一些表数据要不定时统计,一些业务报表的汇总和生成,大量数据导入后台处理,一般都是用定时任务去处理,对于太占资源的任务需要后台处理,越复杂的系统定时任务也越多,需要监控的东西也很多。
而在springBoot提供了简单的定时任务支持,由于Spring Schedule包含在spring-boot-starter基础模块中了,所有不需要增加额外的依赖。
操作步骤
- 初始化项目之后,我们需要在spring boot的入口类Application.java中,允许支持schedule
@SpringBootApplication
@EnableScheduling
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 然后,新建一个执行类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参数说明:
- fixedDelay和fixedRate是最简单的2种方式,多少分钟执行一次,单位是毫秒,所以1分钟就是60秒×1000。
- 他们的区别在于,fixedRate就是每多次分钟一次,不论你业务执行花费了多少时间。我都是1分钟执行1次,而fixedDelay是当任务执行完毕后1分钟在执行。所以根据实际业务不同,我们会选择不同的方式。
而还有一类定时任务,比如是每天的7点15分执行,那么我们就需要用另外一种方式:cron表达式 - 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使用步骤
- 导入pom.xml依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.3</version>
</dependency>
- 新建 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;
}
}
- 测试方法
@Test
void getWeather() {
String weather = GetEmailInfosUtil.getWeather();
System.out.println(weather);
}
- 结果如下
- 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进制的方法