• SpringBoot拉取高德天气预报数据


    SpringBoot拉取高德天气预报数据

    一、账号申请

    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

    在这里插入图片描述
    请勾选web服务
    在这里插入图片描述
    在这里插入图片描述

    二、代码编写

    1.pom.xml

    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0modelVersion>
        <parent>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-parentartifactId>
            <version>2.7.17version>
            <relativePath/> 
        parent>
    
        <groupId>com.qiangesoftgroupId>
        <artifactId>weatherartifactId>
        <version>1.0.0version>
        <name>weathername>
        <description>天气预报description>
    
        <properties>
            <java.version>11java.version>
        properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starterartifactId>
            dependency>
    
            <dependency>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-starter-webartifactId>
            dependency>
    
            <dependency>
                <groupId>org.projectlombokgroupId>
                <artifactId>lombokartifactId>
                <version>1.18.28version>
            dependency>
    
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>8.0.13version>
            dependency>
    
            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plus-boot-starterartifactId>
                <version>3.5.3version>
            dependency>
    
            <dependency>
                <groupId>com.github.xiaoymingroupId>
                <artifactId>knife4j-spring-boot-starterartifactId>
                <version>3.0.3version>
            dependency>
        dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-maven-pluginartifactId>
                plugin>
            plugins>
        build>
    
    project>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    2.配置文件

    server:
      port: 8086
    
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/db_weather?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
        username: root
        password: root
      mvc:
        pathmatch:
          matching-strategy: ant_path_matcher
    
    mybatis-plus:
      type-aliases-package: com.qiangesoft.weather.entity
      mapper-locations: classpath*:mapper/*Mapper.xml
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3.配置类

    package com.qiangesoft.weather.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Contact;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    /**
     * Knife4j的接口配置
     *
     * @author qiangesoft
     */
    @EnableSwagger2
    @EnableWebMvc
    public class Knife4jConfig {
    
        @Bean
        public Docket docket() {
            return new Docket(DocumentationType.SWAGGER_2)
                    // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
                    .apiInfo(this.apiInfo())
                    // 设置哪些接口展示
                    .select()
                    // 扫描指定包
                    .apis(RequestHandlerSelectors.basePackage("com.qiangesoft.weather.controller"))
                    .build();
        }
    
        /**
         * 添加摘要信息
         */
        private ApiInfo apiInfo() {
            // 用ApiInfoBuilder进行定制
            return new ApiInfoBuilder()
                    // 设置标题
                    .title("标题:天气_接口文档")
                    // 描述
                    .description("描述:用于管理天气的接口")
                    // 作者信息
                    .contact(new Contact("qiangesoft", null, null))
                    // 版本
                    .version("v1.0.0")
                    .build();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    package com.qiangesoft.weather.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    /**
     * WebConfiguration
     *
     * @author qiangesoft
     * @date 2023-10-25
     */
    @Configuration
    public class WebConfiguration {
    
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4.实体类

    package com.qiangesoft.weather.entity;
    
    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    
    import java.io.Serializable;
    import java.util.Date;
    
    /**
     * 

    * 实时天气 *

    * * @author qiangesoft * @since 2023-08-10 */
    @Data @EqualsAndHashCode(callSuper = false) public class Weather implements Serializable { private static final long serialVersionUID = 1L; /** * id */ @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 省份名 */ private String province; /** * 城市名 */ private String city; /** * 区域编码 */ private String adcode; /** * 天气现象(汉字描述) */ private String weather; /** * 天气图片 */ private String weatherImg; /** * 实时气温,单位:摄氏度 */ private String temperature; /** * 风向描述 */ private String windDirection; /** * 风力级别,单位:级 */ private String windPower; /** * 空气湿度 */ private String humidity; /** * 数据发布的时间 */ private String reportTime; /** * 创建时间 */ @TableField(fill = FieldFill.INSERT) private Date createTime; }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    package com.qiangesoft.weather.entity;
    
    import com.baomidou.mybatisplus.annotation.FieldFill;
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    
    import java.io.Serializable;
    import java.util.Date;
    
    /**
     * 

    * 预报天气 *

    * * @author qiangesoft * @since 2023-08-10 */
    @Data @EqualsAndHashCode(callSuper = false) public class WeatherForecast implements Serializable { private static final long serialVersionUID = 1L; /** * id */ @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 省份名 */ 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; /** * 创建时间 */ @TableField(fill = FieldFill.INSERT) private Date createTime; }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121

    5.mapper层

    package com.qiangesoft.weather.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.qiangesoft.weather.entity.Weather;
    
    /**
     * 

    * 实时天气 Mapper 接口 *

    * * @author qiangesoft * @since 2023-08-10 */
    public interface WeatherMapper extends BaseMapper<Weather> { }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    package com.qiangesoft.weather.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.qiangesoft.weather.entity.WeatherForecast;
    
    /**
     * 

    * 预报天气 Mapper 接口 *

    * * @author qiangesoft * @since 2023-08-10 */
    public interface WeatherForecastMapper extends BaseMapper<WeatherForecast> { }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    6.服务层

    package com.qiangesoft.weather.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.qiangesoft.weather.entity.Weather;
    
    /**
     * 

    * 实时天气 服务类 *

    * * @author qiangesoft * @since 2023-08-10 */
    public interface IWeatherService extends IService<Weather> { /** * 实时天气 * * @param adcode * @return */ Weather liveWeather(String adcode); }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    package com.qiangesoft.weather.service.impl;
    
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.qiangesoft.weather.entity.Weather;
    import com.qiangesoft.weather.mapper.WeatherMapper;
    import com.qiangesoft.weather.service.IWeatherService;
    import org.springframework.stereotype.Service;
    
    /**
     * 

    * 实时天气 服务实现类 *

    * * @author qiangesoft * @since 2023-08-10 */
    @Service public class WeatherServiceImpl extends ServiceImpl<WeatherMapper, Weather> implements IWeatherService { @Override public Weather liveWeather(String adcode) { LambdaQueryWrapper<Weather> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Weather::getAdcode, adcode) .last("limit 1") .orderByDesc(Weather::getId); return baseMapper.selectOne(queryWrapper); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    package com.qiangesoft.weather.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.qiangesoft.weather.entity.WeatherForecast;
    
    import java.util.List;
    
    /**
     * 

    * 预报天气 服务类 *

    * * @author qiangesoft * @since 2023-08-10 */
    public interface IWeatherForecastService extends IService<WeatherForecast> { /** * 预报天气 * * @param adcode * @return */ List<WeatherForecast> forecastWeather(String adcode); }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    package com.qiangesoft.weather.service.impl;
    
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.qiangesoft.weather.entity.WeatherForecast;
    import com.qiangesoft.weather.mapper.WeatherForecastMapper;
    import com.qiangesoft.weather.service.IWeatherForecastService;
    import org.springframework.stereotype.Service;
    
    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.List;
    
    /**
     * 

    * 预报天气 服务实现类 *

    * * @author qiangesoft * @since 2023-08-10 */
    @Service public class WeatherForecastServiceImpl extends ServiceImpl<WeatherForecastMapper, WeatherForecast> implements IWeatherForecastService { @Override public List<WeatherForecast> forecastWeather(String adcode) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate localDate = LocalDate.now(); String today = localDate.format(formatter); String format1 = localDate.plusDays(1).format(formatter); String format2 = localDate.plusDays(2).format(formatter); LambdaQueryWrapper<WeatherForecast> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(WeatherForecast::getAdcode, adcode) .in(WeatherForecast::getDate, Arrays.asList(today, format1, format2)) .orderByDesc(WeatherForecast::getId) .last("limit 3"); List<WeatherForecast> weatherForecastList = baseMapper.selectList(queryWrapper); weatherForecastList.sort(Comparator.comparing(WeatherForecast::getId)); return weatherForecastList; } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    7.controller层

    package com.qiangesoft.weather.controller;
    
    import com.qiangesoft.weather.entity.Weather;
    import com.qiangesoft.weather.entity.WeatherForecast;
    import com.qiangesoft.weather.service.IWeatherForecastService;
    import com.qiangesoft.weather.service.IWeatherService;
    import com.qiangesoft.weather.utils.ResultInfo;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    
    /**
     * 

    * 实时天气 前端控制器 *

    * * @author qiangesoft * @since 2023-08-10 */
    @RestController @RequestMapping("/weather") @Api(tags = "天气管理") public class WeatherController { @Autowired private IWeatherService weatherService; @Autowired private IWeatherForecastService weatherForecastService; @ApiOperation("实时天气") @GetMapping("/live") public ResultInfo<Weather> liveWeather(String adcode) { return ResultInfo.ok(weatherService.liveWeather(adcode)); } @ApiOperation("预报天气") @GetMapping("/forecast") public ResultInfo<List<WeatherForecast>> forecastWeather(String adcode) { return ResultInfo.ok(weatherForecastService.forecastWeather(adcode)); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    8.核心代码如下

    • 目前使用spring定时任务去拉取天气
    • 分为实时天气和预报天气
    • 实时天气每隔一个小时拉取一次
    • 预报天气分别在每天8、11、18时30分拉取一次
    package com.qiangesoft.weather.gaode;
    
    import com.qiangesoft.weather.entity.Weather;
    import com.qiangesoft.weather.entity.WeatherForecast;
    import com.qiangesoft.weather.gaode.constant.WeatherConstant;
    import com.qiangesoft.weather.gaode.constant.WeatherType;
    import com.qiangesoft.weather.gaode.model.Forecast;
    import com.qiangesoft.weather.gaode.model.GaoDeResult;
    import com.qiangesoft.weather.gaode.model.Live;
    import com.qiangesoft.weather.service.IWeatherForecastService;
    import com.qiangesoft.weather.service.IWeatherService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    import org.springframework.util.CollectionUtils;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 天气数据更新
     *
     * @author qiangesoft
     * @date 2023-07-18
     */
    @Slf4j
    @Component
    public class WeatherTask {
    
        @Autowired
        private RestTemplate restTemplate;
        @Autowired
        private IWeatherService weatherService;
        @Autowired
        private IWeatherForecastService weatherForecastService;
    
        /**
         * 北京市
         * 城市编码表:doc/AMap_adcode_citycode.xlsx
         */
        private static final String AD_CODE = "110000";
    
        /**
         * 实况天气每小时更新多次
         * 每隔一小时执行一次
         */
        @Scheduled(cron = "0 0 0/1 * * ?")
        public void pullLive() {
            log.info("Pull live weather data begin==================>");
            long startTime = System.currentTimeMillis();
    
            // 拉取实时天气
            this.saveLive(AD_CODE);
    
            long endTime = System.currentTimeMillis();
            log.info("spend time:" + (endTime - startTime));
            log.info("Pull live weather data end<==================");
        }
    
        /**
         * 预报天气每天更新3次,分别在8、11、18点左右更新
         * 每天8、11、18点30分执行
         */
        @Scheduled(cron = "0 30 8,11,18 * * ?")
        public void pullForecast() {
            log.info("Pull forecast weather data begin==================>");
            long startTime = System.currentTimeMillis();
    
            // 拉取预报天气
            this.saveForecast(AD_CODE);
    
            long endTime = System.currentTimeMillis();
            log.info("spend time:" + (endTime - startTime));
            log.info("Pull forecast weather data end<==================");
        }
    
        /**
         * 预报天气
         *
         * @param adcode
         */
        private void saveForecast(String adcode) {
            StringBuilder sendUrl = new StringBuilder(WeatherConstant.WEATHER_URL)
                    .append("?key=").append(GaoDeApi.KEY_VALUE)
                    .append("&city=").append(adcode)
                    .append("&extensions=all");
            ResponseEntity<GaoDeResult> responseEntity = restTemplate.getForEntity(sendUrl.toString(), GaoDeResult.class);
            // 请求异常,可能由于网络等原因
            HttpStatus statusCode = responseEntity.getStatusCode();
            if (!HttpStatus.OK.equals(statusCode)) {
                log.info("Request for Gaode interface error");
                return;
            }
    
            // 请求失败
            GaoDeResult gaoDeResult = responseEntity.getBody();
            String status = gaoDeResult.getStatus();
            if (!status.equals(GaoDeApi.SUCCESS)) {
                log.info("Request for Gaode interface failed");
                return;
            }
    
            List<Forecast> forecasts = gaoDeResult.getForecasts();
            if (CollectionUtils.isEmpty(forecasts)) {
                return;
            }
    
            // 预报天气
            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);
            }
            weatherForecastService.saveBatch(weatherForecastList);
        }
    
        /**
         * 实时天气
         *
         * @param adcode
         */
        private void saveLive(String adcode) {
            StringBuilder sendUrl = new StringBuilder(WeatherConstant.WEATHER_URL)
                    .append("?key=").append(GaoDeApi.KEY_VALUE)
                    .append("&city=").append(adcode)
                    .append("&extensions=base");
            ResponseEntity<GaoDeResult> responseEntity = restTemplate.getForEntity(sendUrl.toString(), GaoDeResult.class);
            // 请求异常,可能由于网络等原因
            HttpStatus statusCode = responseEntity.getStatusCode();
            if (!HttpStatus.OK.equals(statusCode)) {
                log.info("Request for Gaode interface error");
                return;
            }
    
            // 请求失败
            GaoDeResult gaoDeResult = responseEntity.getBody();
            String status = gaoDeResult.getStatus();
            if (!status.equals(GaoDeApi.SUCCESS)) {
                log.info("Request for Gaode interface failed");
                return;
            }
    
            List<Live> lives = gaoDeResult.getLives();
            if (CollectionUtils.isEmpty(lives)) {
                return;
            }
    
            // 实况天气
            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());
            weatherService.save(weather);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    package com.qiangesoft.weather.gaode.constant;
    
    /**
     * 天气常量
     *
     * @author qiangesoft
     * @date 2023-08-10
     */
    public class WeatherConstant {
        /**
         * 天气接口地址
         */
        public static final String WEATHER_URL = "https://restapi.amap.com/v3/weather/weatherInfo";
    
        /**
         * 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";
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    package com.qiangesoft.weather.gaode.constant;
    
    /**
     * 天气
     *
     * @author qiangesoft
     * @date 2023-08-11
     */
    public enum WeatherType {
        /**
         * https://lbs.amap.com/api/webservice/guide/tools/weather-code
         * 可参考高德天气对照表
         */
    
        /**
         * 雪
         */
        XUE("xue", "雪"),
    
        /**
         * 雷
         */
        LEI("lei", "雷"),
    
        /**
         * 沙尘
         */
        SHA_CHEN("shachen", "沙尘"),
    
        /**
         * 雾
         */
        WU("wu", "雾"),
    
        /**
         * 冰雹
         */
        BING_BAO("bingbao", "冰雹"),
    
        /**
         * 云
         */
        YUN("yun", "云"),
    
        /**
         * 雨
         */
        YU("yu", "雨"),
    
        /**
         * 阴
         */
        YIN("yin", "阴"),
    
        /**
         * 晴
         */
        QING("qing", "晴");
    
        private String code;
    
        private String des;
    
    
        WeatherType(String code, String des) {
            this.code = code;
            this.des = des;
        }
    
        public String getCode() {
            return code;
        }
    
        public String getDes() {
            return des;
        }
    
        public static String getCodeByDes(String des) {
            for (WeatherType value : values()) {
                if (des.contains(value.getDes())) {
                    return value.getCode();
                }
            }
            return "";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    package com.qiangesoft.weather.gaode.model;
    
    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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    package com.qiangesoft.weather.gaode.model;
    
    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;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    package com.qiangesoft.weather.gaode.model;
    
    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;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    package com.qiangesoft.weather.gaode;
    
    /**
     * 高德API
     *
     * @author qiangesoft
     * @date 2023-07-18
     */
    public class GaoDeApi {
        /**
         * 成功标志
         */
        public static final String SUCCESS = "1";
    
        /**
         * 请求key
         * 

    * 可以申请自己的key:https://lbs.amap.com/dev/key/app */ public static final String KEY_VALUE = "eea81fd695ceeda7bdab6d3e98ecc2ed"; }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    package com.qiangesoft.weather.utils;
    
    import java.io.Serializable;
    
    /**
     * 响应信息主体
     *
     * @author qiangesoft
     */
    public class ResultInfo<T> implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        /**
         * 成功
         */
        public static final int SUCCESS = 200;
    
        /**
         * 失败
         */
        public static final int FAIL = 500;
    
        private int code;
    
        private String msg;
    
        private T data;
    
        public static <T> ResultInfo<T> ok() {
            return restResult(null, SUCCESS, "请求成功");
        }
    
        public static <T> ResultInfo<T> ok(T data) {
            return restResult(data, SUCCESS, "操作成功");
        }
    
        public static <T> ResultInfo<T> ok(T data, String msg) {
            return restResult(data, SUCCESS, msg);
        }
    
        public static <T> ResultInfo<T> fail() {
            return restResult(null, FAIL, "请求失败");
        }
    
        public static <T> ResultInfo<T> fail(String msg) {
            return restResult(null, FAIL, msg);
        }
    
        public static <T> ResultInfo<T> fail(T data) {
            return restResult(data, FAIL, "请求失败");
        }
    
        public static <T> ResultInfo<T> fail(T data, String msg) {
            return restResult(data, FAIL, msg);
        }
    
        public static <T> ResultInfo<T> fail(int code, String msg) {
            return restResult(null, code, msg);
        }
    
        private static <T> ResultInfo<T> restResult(T data, int code, String msg) {
            ResultInfo<T> apiResult = new ResultInfo<>();
            apiResult.setCode(code);
            apiResult.setData(data);
            apiResult.setMsg(msg);
            return apiResult;
        }
    
        public int getCode() {
            return code;
        }
    
        public void setCode(int code) {
            this.code = code;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        public static <T> Boolean isError(ResultInfo<T> ret) {
            return !isSuccess(ret);
        }
    
        public static <T> Boolean isSuccess(ResultInfo<T> ret) {
            return ResultInfo.SUCCESS == ret.getCode();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102

    三、源码仓库

    源码地址:https://gitee.com/qiangesoft/weather

  • 相关阅读:
    分布式计算模型Mapreduce实践与原理剖析(一)
    关于Kubernetes中资源限制的一些笔记整理
    利用Cannon算法证明跨节点的线程通信的代价要远高于本地跨核通信的代价
    3分钟看懂设计模式01:策略模式
    HAproxy:负载均衡
    openGauss学习笔记-119 openGauss 数据库管理-设置数据库审计-设置文件权限安全策略
    【MicroPython ESP32】ssd1306模块基于GB2312字库驱动0.96“I2C屏幕汉字显示示例
    git之分支管理
    【老生谈算法】matlab实现AHP算法源码——AHP算法
    以动态规划的方式求解最长回文子串
  • 原文地址:https://blog.csdn.net/weixin_39311781/article/details/134079187