Java请求Flightradar24接口无法获取更新后JSON数据
问题根因
- 轮询逻辑存在致命判断错误:代码仅在
cache.isEmpty()为真时才执行接口请求、数据解析流程,第一次拉取数据写入缓存后,缓存非空状态下后续轮询根本不会发起新的HTTP请求,自然无法获取更新数据。 - HttpURLConnection默认开启HTTP缓存机制,且未配置禁用缓存的请求头,JVM网络栈、链路中间CDN节点会直接返回首次请求的缓存副本,不会回源拉取实时数据。
- 请求缺少标准标识头,Flightradar24接口侧CDN策略会对无合法标识的请求返回固定缓存内容,不会返回动态实时数据。
- 每次HTTP请求后未主动释放流资源、断开连接,连接复用时可能残留旧响应数据;若存储响应的
StringBuilder content为全局变量,未在每次请求前清空,也会导致旧数据残留。 - JSON解析时用
toString()取值会给字符串类型字段额外包裹双引号,写入CSV会出现格式错误。
具体修改方案
1. 修复轮询逻辑
删掉最外层无意义的if(cache.isEmpty())判断,轮询流程按固定间隔发起请求,每次请求前清空上一轮的临时缓存,避免旧数据残留:
// 轮询主循环,不要加cache.isEmpty()判断 while (true) { long currentTimestamp = System.currentTimeMillis(); long elapsedTimestamp = currentTimestamp - lastTimestamp; long sleep = sleepTime - elapsedTimestamp; if(sleep > 0){ Thread.sleep(sleep); } cache.clear(); // 每次请求前清空上一轮临时缓存 retrieveObject(); lastTimestamp = System.currentTimeMillis(); for (Map.Entry<?, ?> entry : obj.entrySet()) { String flightID = entry.getKey().toString(); JsonArray value = (JsonArray) entry.getValue(); String[] data = new String[20]; for(int i = 0; i < data.length-1; i++){ // 用getAsString()取值,避免多余的引号 data[i] = value.get(i).isJsonNull() ? "" : value.get(i).getAsString(); } data[19] = flightID; cache.push(data); writeToCSV(data); } }
2. 修复HTTP连接配置
初始化连接时主动禁用缓存,补充必要请求头绕过CDN缓存策略,可额外在URL末尾拼接时间戳参数强制回源:
// 每次请求生成带时间戳的新URL,彻底避免命中缓存 String requestUrl = settings[0] + "&_t=" + System.currentTimeMillis(); URL url = new URL(requestUrl); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); // 禁用JVM内置缓存 connection.setUseCaches(false); connection.setDefaultUseCaches(false); // 添加标准请求头 connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"); connection.setRequestProperty("Referer", "https://www.flightradar24.com/"); connection.setRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate"); connection.setRequestProperty("Pragma", "no-cache"); connection.setRequestProperty("Accept", "application/json, text/javascript, */*; q=0.01");
3. 修复资源释放与响应清空逻辑
在retrieveObject()方法开头清空响应存储对象,请求解析完成后在finally块中释放所有资源:
// retrieveObject()方法开头加这行,清空上一次的响应内容 content.setLength(0); BufferedReader reader = null; InputStream is = null; try { // 原有状态码判断、响应读取、JSON解析逻辑 } finally { // 主动释放所有资源 if (reader != null) { try {reader.close();} catch (IOException ignored) {} } if (is != null) { try {is.close();} catch (IOException ignored) {} } if (connection != null) { connection.disconnect(); } }
4. 优化CSV写入逻辑
用try-with-resources自动关闭文件流,直接拼接CSV行避免多余的字符替换:
try (FileWriter writer = new FileWriter("results.csv",true); BufferedWriter bw = new BufferedWriter(writer)) { String line = String.join(",", data); bw.write(line + "\n"); } catch (IOException e) { e.printStackTrace(); }
注意事项
- 轮询间隔建议设置为10~15秒,不要短于5秒,避免被接口侧限流封禁。
- 若后续出现403/429错误,可适当拉长轮询间隔,不要高频请求公开接口。
内容的提问来源于stack exchange,提问作者user19384320
相关产品推荐
相关产品推荐

