一、前言

现在我们的日常开发中获取天气信息已经成为一项很重要的功能,也是一些门户网站必不可少的展示。所以我们需要学习如何获取实时天气数据,我们利用SpringBoot集成高德天气API可以很方便的实现获取天气实时数据。

二、前期准备

1.账号申请

天气文档:https://lbs.amap.com/api/webservice/guide/api/weatherinfo

整体流程可参考:https://lbs.amap.com/api/webservice/guide/create-project/get-key

2.注册账号

注册地址:https://console.amap.com/dev/id/phone

3.创建应用

地址:https://console.amap.com/dev/key/app

4.申请key

SpringBoot集成高德天气API获取天气数据_天气API

5.请勾选web服务

SpringBoot集成高德天气API获取天气数据_天气API_02

三、项目实战

1.填写相关配置和创建配置类

#高德天气请求路径
amap-weather-config.weatherurl=https://restapi.amap.com/v3/weather/weatherInfo
#高德地图申请的key
amap-weather-config.key=xxxxx
package com.example.dataproject.config;

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @author qx
 * @date 2024/9/13
 * @des 高德天气属性配置
 */
@Configuration
@ConfigurationProperties(prefix = "amap-weather-config")
@Getter
@Setter
public class AmapWeatherConfig {

    /**
     * 请求路径
     */
    private String weatherurl;

    /**
     * key
     */
    private String key;
}

2.配置RestTemplate

package com.example.dataproject;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;


@SpringBootApplication
public class DataProjectApplication {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(DataProjectApplication.class, args);
    }

}

3.创建相关实体类

实时天气

package com.example.dataproject.domain;

import lombok.Data;

/**
 * 实况天气
 *
 * @author qiangesoft
 * @date 2023-08-10
 */
@Data
public class Live {

    /**
     * 省份名
     */
    private String province;

    /**
     * 城市名
     */
    private String city;

    /**
     * 区域编码
     */
    private String adcode;

    /**
     * 天气现象(汉字描述)
     */
    private String weather;

    /**
     * 实时气温,单位:摄氏度
     */
    private String temperature;

    /**
     * 风向描述
     */
    private String winddirection;

    /**
     * 风力级别,单位:级
     */
    private String windpower;

    /**
     * 空气湿度
     */
    private String humidity;

    /**
     * 数据发布的时间
     */
    private String reporttime;

}

预报天气

package com.example.dataproject.domain;


import lombok.Data;

import java.util.List;

/**
 * 预报天气
 *
 * @author qiangesoft
 * @date 2023-08-10
 */
@Data
public class Forecast {

    /**
     * 省份名
     */
    private String province;

    /**
     * 城市名
     */
    private String city;

    /**
     * 区域编码
     */
    private String adcode;

    /**
     * 数据发布的时间
     */
    private String reporttime;

    /**
     * 天气
     */
    private List<Cast> casts;

    /**
     * 详细天气信息
     */
    @Data
    public static class Cast {

        /**
         * 日期
         */
        private String date;

        /**
         * 星期几
         */
        private String week;

        /**
         * 白天天气现象
         */
        private String dayweather;

        /**
         * 晚上天气现象
         */
        private String nightweather;

        /**
         * 白天温度
         */
        private String daytemp;

        /**
         * 晚上温度
         */
        private String nighttemp;

        /**
         * 白天风向
         */
        private String daywind;

        /**
         * 晚上风向
         */
        private String nightwind;

        /**
         * 白天风力
         */
        private String daypower;

        /**
         * 晚上风力
         */
        private String nightpower;
    }
}

高德天气数据结果实体

package com.example.dataproject.domain;


import lombok.Data;

import java.util.List;

/**
 * 高德数据结果
 *
 * @author qiangesoft
 * @date 2023-07-18
 */
@Data
public class GaoDeResult {
    /**
     * 返回结果状态值
     */
    private String status;
    /**
     * 返回状态说明
     */
    private String info;
    /**
     * 状态码
     */
    private String infocode;
    /**
     * 查询个数
     */
    private String count;
    /**
     * 实况天气数据信息
     */
    private List<Live> lives;
    /**
     * 预报天气信息数据
     */
    private List<Forecast> forecasts;

}

天气常量类

package com.example.dataproject.common;


/**
 * 天气常量
 *
 * @author qiangesoft
 * @date 2023-08-10
 */
public class WeatherConstant {

    /**
     * 成功标志
     */
    public static final String SUCCESS = "1";


    /**
     * key
     */
    public static final String KEY = "key";

    /**
     * 输入城市的adcode
     */
    public static final String CITY = "city";

    /**
     * 可选值:base/all
     * base:返回实况天气
     * all:返回预报天气
     */
    public static final String EXTENSIONS = "extensions";

    /**
     * 可选值:JSON,XML
     */
    public static final String OUTPUT = "output";
}

4.天气服务层

package com.example.dataproject.service;

import com.example.dataproject.common.WeatherConstant;
import com.example.dataproject.config.AmapWeatherConfig;
import com.example.dataproject.domain.*;
import com.example.dataproject.enums.WeatherType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author qx
 * @date 2024/9/12
 * @des 高德天气服务层
 */
@Service
@Slf4j
public class WeatherService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private AmapWeatherConfig amapWeatherConfig;


    /**
     * 实时天气
     *
     * @param adcode
     * @return
     */
    public Weather getData(String adcode) {
        String sendUrl = amapWeatherConfig.getWeatherurl() +
                "?key=" + amapWeatherConfig.getKey() +
                "&city=" + adcode +
                "&extensions=base";
        ResponseEntity<GaoDeResult> responseEntity = restTemplate.getForEntity(sendUrl, GaoDeResult.class);
        // 请求异常,可能由于网络等原因
        HttpStatus statusCode = responseEntity.getStatusCode();
        if (!HttpStatus.OK.equals(statusCode)) {
            log.info("Request for Gaode interface error");
            return null;
        }
        // 请求失败
        GaoDeResult gaoDeResult = responseEntity.getBody();
        String status = gaoDeResult.getStatus();
        if (!status.equals(WeatherConstant.SUCCESS)) {
            log.info("Request for Gaode interface failed");
            return null;
        }

        List<Live> lives = gaoDeResult.getLives();
        if (CollectionUtils.isEmpty(lives)) {
            return null;
        }
        // 实况天气
        Live live = lives.get(0);
        Weather weather = new Weather();
        weather.setProvince(live.getProvince());
        weather.setCity(live.getCity());
        weather.setAdcode(live.getAdcode());
        weather.setWeather(live.getWeather());
        weather.setWeatherImg(WeatherType.getCodeByDes(live.getWeather()));
        weather.setTemperature(live.getTemperature());
        weather.setWindDirection(live.getWinddirection());
        weather.setWindPower(live.getWindpower());
        weather.setHumidity(live.getHumidity());
        weather.setReportTime(live.getReporttime());
        return weather;
    }

    /**
     * 预报天气
     *
     * @param adcode
     * @return
     */
    public List<WeatherForecast> getForecastData(String adcode) {
        String sendUrl = amapWeatherConfig.getWeatherurl() +
                "?key=" + amapWeatherConfig.getKey() +
                "&city=" + adcode +
                "&extensions=all";
        ResponseEntity<GaoDeResult> responseEntity = restTemplate.getForEntity(sendUrl, GaoDeResult.class);
        // 请求异常,可能由于网络等原因
        HttpStatus statusCode = responseEntity.getStatusCode();
        if (!HttpStatus.OK.equals(statusCode)) {
            log.info("Request for Gaode interface error");
            return Collections.emptyList();
        }

        // 请求失败
        GaoDeResult gaoDeResult = responseEntity.getBody();
        String status = gaoDeResult.getStatus();
        if (!status.equals(WeatherConstant.SUCCESS)) {
            log.info("Request for Gaode interface failed");
            return Collections.emptyList();
        }

        List<Forecast> forecasts = gaoDeResult.getForecasts();
        if (CollectionUtils.isEmpty(forecasts)) {
            return Collections.emptyList();
        }

        // 预报天气
        Forecast forecast = forecasts.get(0);
        List<WeatherForecast> weatherForecastList = new ArrayList<>();
        List<Forecast.Cast> casts = forecast.getCasts();
        for (Forecast.Cast cast : casts) {
            WeatherForecast weatherForecast = new WeatherForecast();
            weatherForecast.setProvince(forecast.getProvince());
            weatherForecast.setCity(forecast.getCity());
            weatherForecast.setAdcode(forecast.getAdcode());
            weatherForecast.setDate(cast.getDate());
            weatherForecast.setWeek(cast.getWeek());
            weatherForecast.setDayWeather(cast.getDayweather());
            weatherForecast.setDayWeatherImg(WeatherType.getCodeByDes(cast.getDayweather()));
            weatherForecast.setNightWeather(cast.getNightweather());
            weatherForecast.setNightWeatherImg(WeatherType.getCodeByDes(cast.getNightweather()));
            weatherForecast.setDayTemp(cast.getDaytemp());
            weatherForecast.setNightTemp(cast.getNighttemp());
            weatherForecast.setDayWind(cast.getDaywind());
            weatherForecast.setNightWind(cast.getNightwind());
            weatherForecast.setDayPower(cast.getDaypower());
            weatherForecast.setNightPower(cast.getNightpower());
            weatherForecast.setReportTime(forecast.getReporttime());
            weatherForecastList.add(weatherForecast);
        }
        return weatherForecastList;
    }
}

5.创建控制层

package com.example.dataproject.controller;

import com.example.dataproject.domain.*;
import com.example.dataproject.service.WeatherService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author qx
 * @date 2024/9/12
 * @des
 */
@RestController
@Slf4j
public class WeatherController {

    @Autowired
    private WeatherService weatherService;


    /**
     * 实时天气
     *
     * @param adcode 行政编码
     * @return
     */
    @GetMapping("/getWeather")
    public Weather getData(String adcode) {
        return weatherService.getData(adcode);
    }

    /**
     * 预告天气
     *
     * @param adcode 行政编码
     * @return
     */
    @GetMapping("/getForecatWeather")
    public List<WeatherForecast> getForecastData(String adcode) {
        return weatherService.getForecastData(adcode);
    }
}

6.启动程序进行测试

输入城市编码表进行测试,具体的城市编码表在高德地图上也提供了支持。

https://lbs.amap.com/api/webservice/download

SpringBoot集成高德天气API获取天气数据_高德地图_03

获取实时天气

SpringBoot集成高德天气API获取天气数据_天气API_04

获取预报天气

SpringBoot集成高德天气API获取天气数据_高德地图_05