天气API使用记

需求

做了一个系统,里面要显示天气信息,不是实时天气,而是历史天气,好多天,任何天,具体哪天,要看用户在页面上选择的日期是哪天。

方案调研

最开始想到了高德地图,它提供了天气API,但是后来发现它提供的是当前实时天气的API,系统中还有要显示2019年天气的地方,不合适。

在网上又找了几个免费的,网页的。发请求,得到网页内容之后,使用正则、XPath等各种魔法,解析内容,获得天气。刚开始可以跑,后来发现数据有限,跑着跑着就没数据了,代码都写好了,发现数据没有了,好烦。

最终找到了易客云的天气API,实时天气、历史天气、降水、气温等等,各类专业的API,非常好,调接口得到的就是JSON,直接缓存到Redis并入MySQL,下次就不调他了,直接从自己的缓存中取,缓存中没有去就数据库中取,搞定!

易客云天气API使用

使用非常简单,去官网 易客云天气API免费天气API接口|天气预报接口|全球天气API接口|气象预警|空气质量 注册一个账号:

会免费送许多额度:

就可以开始调用了。

调用的地址、参数都在官方文档中,一个HTTP get请求就搞定了,还不是HTTPS的,HTTP即可,又快又省事,太简单了。以获取历史天气信息为例:

接口地址:

http://v1.yiketianqi.com/free/history?appid=96142279&appsecret=x7lVy6Bk&cityid=101120101&year=2022&month=1

在这里我使用hutool的HTTP请求工具,不再单独写HTTPConnection的封装了:

@Override
public Object pullHistoryWeather2(String year, String month) {
    String body;
    Object o = objectRedisTemplate.opsForHash().get(Constants.WEATHER_YI_KE_TIAN_QI_LIMITED, year + "-" + month);
    if (o == null) {
        // 这是个付费接口,要严格限制它的调用次数,防止被攻击刷钱
        String url = String.format("http://v0.yiketianqi.com/api?version=history&appid=123&appsecret=abc&adcode=330100000000&year=%s&month=%s", year, month);
        LocalDateTime start = LocalDateTime.now();
        HttpRequest httpRequest = HttpUtil.createGet(url);
        HttpResponse httpResponse = httpRequest.execute();
        int status = httpResponse.getStatus();
        if (status != HttpStatus.HTTP_OK) {
            return "第三方接口失败,状态码:" + status;
        }
        body = httpResponse.body();
        if (StringUtils.isBlank(body)) {
            return "第三方接口失败,响应为空";
        }
        log.info("请求完成,URL:{},耗时:{},响应:{}", url, Duration.between(start, LocalDateTime.now()), body);
        objectRedisTemplate.opsForHash().put(Constants.WEATHER_YI_KE_TIAN_QI_LIMITED, year + "-" + month, body);
        objectRedisTemplate.expire(Constants.WEATHER_YI_KE_TIAN_QI_LIMITED, 365, TimeUnit.DAYS);
    } else {
        body = o.toString();
        if (StringUtils.isBlank(body)) {
            return "缓存的第三方接口失败响应为空";
        }
    }
    JSONObject parsedObject = JSON.parseObject(body);
    JSONArray data = parsedObject.getJSONArray("data");
    for (int i = 0; i < data.size(); i++) {
        JSONObject jsonObject = data.getJSONObject(i);
        String ymd = jsonObject.getString("ymd");
        String tianQi = jsonObject.getString("tianqi");
        Weather row = new Weather();
        row.setDate(ymd);
        row.setWeather(tianQi);
        weatherMapper.insertOrUpdate(row);
    }
    return "成功";
}

代码很简单,发请求之前,先去Redis中找,如果找到了,就不去调接口了,如果没找到,再调接口,避免给接口造成太大压力,或者资源浪费。

最后说一点,这个接口它查历史天气的时候,支持按年月查,这个就方便很多了。不必自己反复计算哪天到哪天差几天漏哪天什么的。一个for循环,搞定。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

互联网速递520

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值