一、前言
对于接口数据的访问,我们必须清楚一点,那就是被访问的地址必须以合法途径获取,否则将会导致严重后果。本文大部分封装内容为snowy开源框架中的内容。
二、代码结构
获取接口数据干嘛用?自然是写到自己的数据库,再对这些数据进行二次利用,所以依然要建立entity、mapper、service、controller等文件。唯一不同的是,需要多建立一个文件夹,存放我们的定时任务相关的东西,包括定时任务逻辑,参数,接口地址,获取方法(get请求)
三、代码部分
这里省略了实体类、控制层等的书写
pom依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
接口路径
统一管理接口访问路径,方便日后调用
public class UrlConstant {
public static String first = "http://某个地址";
}
参数
这里的参数是拼接在路径后面的查询条件
public class DateUtil {
public static String YYYY_MM_DD = "yyyy-MM-dd";
public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static String YYYYMMDD_FOR_CHINA = "yyyy年MM月dd日";
//以获取当前日期为例,例如 2022-11-11
public static final String dateTimeNow(final String format) {
return parseDateToStr(format, new Date ());
}
public static final String parseDateToStr(final String format, final Date date) {
return new SimpleDateFormat (format).format(date);
}
}
HTTP解析
这里借鉴了snowy开源框架中的内容,版权归snowy团队所有
public class HttpUtil {
public static String getData(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader (
connection.getInputStream(),"utf-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
}
service层
public interface ApiServiceInfo {
public String first(String url,String params);
}
impl
这里也是借鉴了snowy开源框架的内容,版权归snowy团队所有。
@Service
public class ApiServiceInfoImpl implements ApiServiceInfo {
@Override
public String first(String url, String params) {
String result = null;
try {
result = HttpUtil.getData(url,params);
} catch (Exception e) {
}
return result;
}
}
重点:定时器执行的业务逻辑
@Component
public class FirstTimer {
@Autowired
public ApiServiceInfo apiServiceInfo;
@Resource
private EntityMapper entityMapper;
//定时器 10000代表每10秒执行一次
@Scheduled(fixedDelay = 10000)
private void first(){
//拼接参数
String params = "startDate="+ DateUtil.dateTimeNow (DateUtil.YYYY_MM_DD);
//获取访问接口数据
String res = apiServiceInfo.first (UrlConstant.first,params);
//如果数据为数组,那么可以省略一下两行,直接执行if判断或其他内容
JSONObject jsonObject = JSONObject.parseObject (res);
//getJSONArray("data")中的data表示要做遍历的原始数组,格式为:[{},{},...]
JSONArray data = jsonObject.getJSONArray ("data");
if (data.size () == 0){
System.out.println ("数组为空");
}else {
JSONArray jsonArray = null;
//这里利用try catch
try {
jsonArray = JSONArray.parseArray (String.valueOf (data));
//for循环
for (Object object : jsonArray){
String objectStr = JSONObject.toJSONString (object);
JSONObject json = JSONObject.parseObject (objectStr);
Entity entity = new Entity ();
entity.setId (json.getString ("Id"));
//这里根据ID先对实体类对应的数据库表进行查询
List<Entity> list = entityMapper.list(Id);
//如果查询不到这个ID对应的数据,那么list.size()==0就会为true,则执行下一步,之所以作如此判断,是为了防止数据重复写入。
if (list.size () == 0){
//当你导入mybatis-plus以后,可以直接利用mapper.insert将实体类进行写入。
entityMapper.insert (entity);
}
}
}catch (Exception e){
}
}
}
}