开发者

SpringBoot整合高德地图实现天气预报功能

目录
  • 一、前言
  • 二、环境搭建
    • (一)创建SpringBoot项目
    • (二)添加依赖
    • (三)高德地图API申请
  • 三、代码实现
    • (一)配置类
    • (二)实体类
    • (三)服务层
    • (四)实体类GaoDeResult和Forecast
    • (五)控制器层
    • (六)定时任务
    • (七)工具类WeatherConstant和WeatherType
  • 四、测试与运行
    • (一)启动项目
    • (二)测试接口
    • (三)查看定时任务
  • 五、总结

    一、前言

    在当今数字化时代,天气预报功能在众多应用中扮演着重要角色。通过整合高德地图提供的天气API,我们可以轻松地在自己的SpringBoot项目中实现这一功能,为用户提供实时和未来几天的天气信息。本文将详细介绍如何在SpringBoot项目中整合高德地图的天气预报功能,包括环境搭建、代码实现、定时任务设置等关键步骤,确保大家能够按照教程成功实现功能。

    二、环境搭建

    (一)创建SpringBoot项目

    • 使用Spring Initializr

      • 访问 Spring Initializr 网站。
      • 选择项目元数据,如项目名称、包名等。
      • 添加依赖:Spring WebSpring Boot DevTools(可选,方便开发时热部署)。
      • 点击“Generate”按钮下载项目压缩包,解压后导入到你的IDE(如IntelliJ IDEA或Eclipse)中。
    • 项目结构示例

    spring-boot-weather
    ├── src
    │   ├── main
    │   │   ├── Java
    │   │   │   └── com.example.weather
    │   │   │       ├── controller
    │   │   │       ├── service
    │   │   │       ├── entity
    │   │   │       ├── config
    │   │   │       └── WeatherApplication.java
    │   │   └── resources
    │   │       ├── application.yml
    │   │       └── static
    │   └── test
    │       └── java
    │           └── com.example.weather
    │               └── WeatherApplicationTests.java
    └── pom.XML
    

    (二)添加依赖

    pom.xml文件中添加必要的依赖,确保项目能够使用Spring Web和定时任务等功能。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    

    (三)高德地图API申请

    • 注册高德开放平台账号

      • 访问 高德开放平台 官网,注册账号并登录。
      • 在“控制台”中创建应用,获取API Key。该Key将用于后续调用高德地图的天气API。
    • 配置application.yml

      • 将获取到的API Key和天气API的URL配置到application.yml文件中。
    amap-weather-config:
      weatherurl: https://restapi.amap.com/v3/weather/weatherInfo
      key: YOUR_API_KEY
    

    三、代码实现

    (一)配置类

    创建一个配置类AmapWeatherConfig,用于读取application.yml中的高德地图天气API配置。

    package com.example.weather.config;
    
    import lombok.Getter;
    import lombok.Setter;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @ConfigurationProperties(prefix = "amap-weather-config")
    @Getter
    @Setter
    public class AmapWeatherConfig {
        private String weatherurl;
        private String key;
    }
    

    (二)实体类

    定义两个实体类LiveWeatherForecast,分别用于存储实时天气和预报天气的数据。

    实时天气实体类Live

    package com.example.weather.entity;
    
    import lombok.Data;
    
    @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;
    }
    

    预报天气实体类WeatherForecast

    package com.example.weather.entity;
    
    import lombok.Data;
    
    @Data
    public class WeatherForecast {
        private String province;
        private String city;
        private String adcode;
        private String date;
        private String week;
        private String dayWeather;
        private String dayWeatherImg;
        private String nightWeather;
        private String nightWeatherImg;
        private String dayTemp;
        private String nightTemp;
        private String dayWind;
        private String nightWind;
        private String dayPower;
        private String nightPower;
        private String reportTime;
    }
    

    (三)服务层

    创建WeatherService类,用于调用高德地图的天气API,并将返回的数据封装到实体类中。

    package com.example.weather.service;
    
    import com.example.weather.config.AmapWeatherConfig;
    import com.example.weather.entity.Live;
    import com.example.weather.entity.WeatherForecast;
    import com.example.weather.common.WeatherConstant;
    import com.example.weather.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;
    
    @Service
    @Slf4j
    public class WeatherService {
        @Autowired
        private RestTemplate restTemplate;
    
        @Autowired
        private AmapWeatherConfig amapWeatherConfig;
    
        /**
         * 获取实时天气
         *
         * @param adcode 城市编码
         * @return 实时天气实体类
         */
        public Live getLiveWeather(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;
            }
      javascript      // 请求失败
            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;
            }
            // 实况天气
            return lives.get(0);
        }
    
        /**
         * 获取未来几天的天气预报
         *
         * @param adcode 城市编码
         * @return 天气预报列表
         */
        public List<WeatherForecast> getForecastWeather(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;
        }
    }
    

    (四)实体类GaoDeResult和Forecast

    高德地图API返回的数据结构较为复杂,需要定义GaoDeResultForecast类来接收和处理这些数据。

    GaoDeResult

    package com.example.weather.entity;
    
    import com.fasterxml.jackson.annotation.jsonProperty;
    import lombok.Data;
    
    import java.util.List;
    
    @Data
    public class GaoDeResult {
        private String status;
        private String info;
        private String infocode;
        @JsonProperty("lives")
        private List<Live> lives;
        @JsonProperty("forecasts")
        private List<Forecast> forecasts;
    }
    

    Forecast

    package com.example.weather.entity;
    
    import com.fasterxml.jackson.annotation.JsonProperty;
    import lombok.Data;
    
    import java.util.List;
    
    @Data
    public class Forecast {
        private String province;
        private String city;
        private String adcode;
        private String reporttime;
        @JsonProperty("casts")
        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;
        }
    }
    

    (五)控制器层

    创建WeatherController类,用于处理前端请求,并调用服务层的方法获取天气数据。

    package com.example.weather.controller;
    
    import com.example.weather.entity.Live;
    import com.example.weather.entity.WeatherForecast;
    import com.example.weather.service.WeatherService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    @RestController
    @RequestMapping("/weather")
    public class WeatherController {
        @Autowired
        private WeatherService weatherService;
    
        /**
         * 获取实时天气
         *
         * @param adcode 城市编码
         * @return 实时天气数据
         */
        @GetMapping("/live")
        public Live getLiveWeather(@RequestParam String adcode) {
            return weatherService.getLiveWeather(adcode);
        }
    
        /**
         * 获取未来几天的天气预报
         *
         * @param adcode 城市编码
         * @return 天气预报数据
         */
        @GetMapping("/forecast")
        public List<WeatherForecast> getForecastWeather(@RequestParam String adcode) {
            return weatherService.getForecastWeather(adcode);
        }
    }
    

    (六)定时任务

    为了定期更新天气数据,可以使用Spring的定时任务功能。创建WeatherTask类,设置定时任务。

    package com.example.weather.task;
    
    import com.example.weather.entity.Live;
    import com.example.weather.entity.WeatherForecast;
    import com.example.weather.service.WeatherService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    
    @Component
    public class WeatherTask {
        @Autowired
        private WeatherService weatherService;
    
        // 每天凌晨3点更新天气数据
        @Scheduled(cron = "0 0 3 * * ?")
        public void updateWeatherData() {
            // 假设我javascript们更新北京的天气数据,北京的城市编码为110000
            String adcode = "110000";
    
            // 更新实时天气
            Live liveWeather = weatherService.getLiveWeather(adcode);
            if (liveWeather != null) {
                // 将实时天气数据存储到数据库或缓存中
                System.out.println("实时天气数据已更新:" + liveWeather);
            }
    
            // 更新未来几天的天气预报
            List<WeatherForecast> forecastWeatherList = weatherService.getForecastWeather(adcode);
            if (!forecastWeatherList.isEmpty()) {
                // 将天气预报数据存储到数据库或缓存中
                System.out.println("天气预报数据已更新:" + forecastWeatherList);
            }
        }
    }
    

    (七)工具类WeatherConstant和WeatherType

    为了方便处理天气数据,创建WeatherConstant类用于定义常量,WeatherType类用于处理天气类型的映射。

    WeatherConstant

    package com.example.weather.common;
    
    public class WeatherConstant {
        public static final String SUCCESS = "1";
    }
    

    WeatherType

    package com.example.weather.enums;
    
    import lombok.Getter;
    
    public enum WeatherType {
        SUNNY("晴", "01"),
        CLOUDY("多云", "02"),
        OVERCAST("阴", "03"),
        LIGHT_RAIN("小雨", "04"),
        MODERATE_RAIN("中雨", "05"),
        HEAVY_RAIN("大雨", "06"),
        STORM("暴雨", "07"),
        FOG("雾", "08"),
        HAZE("霾", "09"),
        SAND("沙尘暴", "10"),
        WIND("大风", "11"),
        SNOW("雪", "12");
    
        @Getter
        private final String description;
        www.devze.com@Getter
        private final String code;
    
        WeatherType(String description, String code) {
            this.description = description;
            this.code = code;
        }
    
        public static String getCodeByDes(String description) {
            for (WeatherType type : WeatherType.values()) {
                if (type.getDescription().equals(description)) {
                    return type.getCode();
                }
            }
            return "";
        }
    }
    

    四、测试与运行

    (一)启动项目

    在IDE中运行WeatherApplication类的main方法,启动SpringBoot项目。

    (二)测试接口

    使用Postman或浏览器访问以下接口进行测试:

    • 实时天气接口http://localhost:8080/weather/live?adcode=110000
    • 天气预报接口http://localhost:8080/weather/forecast?adcode=110000

    (三)查看定时任务

    查看控制台输出,确认定时任务是否正常运行,天气数据是否按时更新。

    五、总结

    通过本文的详细步骤,我们成功地在SpringBoot项目中整合了高德地图的天气预报功能。从环境搭建到代码实现,再到定时任务的设置,每一步都清晰明确,确保大家能够按照教程直接上手操作。在实际开发中,可以根据需求进一步优化和扩展功能,例如将天气数据存储到数据库中,或者为用户提供更多城市的天气查询服务。

    以上就是SpringBoot整合高德地图实现天气预报功能的详细内容,更多关于SpringBoot高德地图天气预报的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜