SpringBoot拉取高德天气预报数据

阅读: 评论:0

SpringBoot拉取高德天气预报数据

SpringBoot拉取高德天气预报数据

SpringBoot拉取高德天气预报数据

一、账号申请

1.整体流程

天气文档:
整体流程可参考:

2.注册账号

注册地址:


3.创建应用

地址:

4.申请key


请勾选web服务

二、代码编写

l

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns=".0.0" xmlns:xsi=""xsi:schemaLocation=".0.0 .0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.17</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.qiangesoft</groupId><artifactId>weather</artifactId><version>1.0.0</version><name>weather</name><description>天气预报</description><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.13</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.3</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.配置文件

server:port: 8086spring:datasource:driver-class-name: sql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/db_weather?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8username: rootpassword: rootmvc:pathmatch:matching-strategy: ant_path_matchermybatis-plus:type-aliases-package: com.itymapper-locations: classpath*:mapper/*l

3.配置类

package com.fig;import t.annotation.Bean;
import org.springframework.fig.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 {@Beanpublic Docket docket() {return new Docket(DocumentationType.SWAGGER_2)// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息).apiInfo(this.apiInfo())// 设置哪些接口展示.select()// 扫描指定包.apis(RequestHandlerSelectors.basePackage("com.ller")).build();}/*** 添加摘要信息*/private ApiInfo apiInfo() {// 用ApiInfoBuilder进行定制return new ApiInfoBuilder()// 设置标题.title("标题:天气_接口文档")// 描述.description("描述:用于管理天气的接口")// 作者信息.contact(new Contact("qiangesoft", null, null))// 版本.version("v1.0.0").build();}
}
package com.fig;import t.annotation.Bean;
import t.annotation.Configuration;
import org.springframework.web.client.RestTemplate;/*** WebConfiguration** @author qiangesoft* @date 2023-10-25*/
@Configuration
public class WebConfiguration {@Beanpublic RestTemplate restTemplate() {return new RestTemplate();}
}

4.实体类

package com.ity;import batisplus.annotation.FieldFill;
import batisplus.annotation.IdType;
import batisplus.annotation.TableField;
import batisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;import java.io.Serializable;
import java.util.Date;/*** <p>* 实时天气* </p>** @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;}
package com.ity;import batisplus.annotation.FieldFill;
import batisplus.annotation.IdType;
import batisplus.annotation.TableField;
import batisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;import java.io.Serializable;
import java.util.Date;/*** <p>* 预报天气* </p>** @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;}

5.mapper层

package com.qiangesoft.weather.mapper;import apper.BaseMapper;
import com.ity.Weather;/*** <p>* 实时天气 Mapper 接口* </p>** @author qiangesoft* @since 2023-08-10*/
public interface WeatherMapper extends BaseMapper<Weather> {}
package com.qiangesoft.weather.mapper;import apper.BaseMapper;
import com.ity.WeatherForecast;/*** <p>* 预报天气 Mapper 接口* </p>** @author qiangesoft* @since 2023-08-10*/
public interface WeatherForecastMapper extends BaseMapper<WeatherForecast> {}

6.服务层

package com.qiangesoft.weather.service;import sion.service.IService;
import com.ity.Weather;/*** <p>* 实时天气 服务类* </p>** @author qiangesoft* @since 2023-08-10*/
public interface IWeatherService extends IService<Weather> {/*** 实时天气** @param adcode* @return*/Weather liveWeather(String adcode);}
package com.qiangesoft.weather.service.impl;import ditions.query.LambdaQueryWrapper;
import sion.service.impl.ServiceImpl;
import com.ity.Weather;
import com.qiangesoft.weather.mapper.WeatherMapper;
import com.qiangesoft.weather.service.IWeatherService;
import org.springframework.stereotype.Service;/*** <p>* 实时天气 服务实现类* </p>** @author qiangesoft* @since 2023-08-10*/
@Service
public class WeatherServiceImpl extends ServiceImpl<WeatherMapper, Weather> implements IWeatherService {@Overridepublic Weather liveWeather(String adcode) {LambdaQueryWrapper<Weather> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(Weather::getAdcode, adcode).last("limit 1").orderByDesc(Weather::getId);return baseMapper.selectOne(queryWrapper);}
}
package com.qiangesoft.weather.service;import sion.service.IService;
import com.ity.WeatherForecast;import java.util.List;/*** <p>* 预报天气 服务类* </p>** @author qiangesoft* @since 2023-08-10*/
public interface IWeatherForecastService extends IService<WeatherForecast> {/*** 预报天气** @param adcode* @return*/List<WeatherForecast> forecastWeather(String adcode);
}
package com.qiangesoft.weather.service.impl;import ditions.query.LambdaQueryWrapper;
import sion.service.impl.ServiceImpl;
import com.ity.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;/*** <p>* 预报天气 服务实现类* </p>** @author qiangesoft* @since 2023-08-10*/
@Service
public class WeatherForecastServiceImpl extends ServiceImpl<WeatherForecastMapper, WeatherForecast> implements IWeatherForecastService {@Overridepublic List<WeatherForecast> forecastWeather(String adcode) {DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");LocalDate localDate = w();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(Comparatorparing(WeatherForecast::getId));return weatherForecastList;}
}
package com.ller;import com.ity.Weather;
import com.ity.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;/*** <p>* 实时天气 前端控制器* </p>** @author qiangesoft* @since 2023-08-10*/
@RestController
@RequestMapping("/weather")
@Api(tags = "天气管理")
public class WeatherController {@Autowiredprivate IWeatherService weatherService;@Autowiredprivate 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));}}

8.核心代码如下

  • 目前使用spring定时任务去拉取天气
  • 分为实时天气和预报天气
  • 实时天气每隔一个小时拉取一次
  • 预报天气分别在每天8、11、18时30分拉取一次
package com.qiangesoft.weather.gaode;import com.ity.Weather;
import com.ity.WeatherForecast;
import com.qiangesoft.stant.WeatherConstant;
import com.qiangesoft.stant.WeatherType;
import com.qiangesoft.del.Forecast;
import com.qiangesoft.del.GaoDeResult;
import com.qiangesoft.del.Live;
import com.qiangesoft.weather.service.IWeatherForecastService;
import com.qiangesoft.weather.service.IWeatherService;
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 {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate IWeatherService weatherService;@Autowiredprivate 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 = String(), GaoDeResult.class);// 请求异常,可能由于网络等原因HttpStatus statusCode = StatusCode();if (!HttpStatus.OK.equals(statusCode)) {log.info("Request for Gaode interface error");return;}// 请求失败GaoDeResult gaoDeResult = Body();String status = Status();if (!status.equals(GaoDeApi.SUCCESS)) {log.info("Request for Gaode interface failed");return;}List<Forecast> forecasts = Forecasts();if (CollectionUtils.isEmpty(forecasts)) {return;}// 预报天气Forecast forecast = (0);List<WeatherForecast> weatherForecastList = new ArrayList<>();List<Forecast.Cast> casts = Casts();for (Forecast.Cast cast : casts) {WeatherForecast weatherForecast = new WeatherForecast();weatherForecast.Province());weatherForecast.City());weatherForecast.Adcode());weatherForecast.Date());weatherForecast.Week());weatherForecast.Dayweather());weatherForecast.Dayweather()));weatherForecast.Nightweather());weatherForecast.Nightweather()));weatherForecast.Daytemp());weatherForecast.Nighttemp());weatherForecast.Daywind());weatherForecast.Nightwind());weatherForecast.Daypower());weatherForecast.Nightpower());weatherForecast.Reporttime());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 = String(), GaoDeResult.class);// 请求异常,可能由于网络等原因HttpStatus statusCode = StatusCode();if (!HttpStatus.OK.equals(statusCode)) {log.info("Request for Gaode interface error");return;}// 请求失败GaoDeResult gaoDeResult = Body();String status = Status();if (!status.equals(GaoDeApi.SUCCESS)) {log.info("Request for Gaode interface failed");return;}List<Live> lives = Lives();if (CollectionUtils.isEmpty(lives)) {return;}// 实况天气Live live = (0);Weather weather = new Weather();weather.Province());weather.City());weather.Adcode());weather.Weather());weather.Weather()));weather.Temperature());weather.Winddirection());weather.Windpower());weather.Humidity());weather.Reporttime());weatherService.save(weather);}}
package com.qiangesoft.stant;/*** 天气常量** @author qiangesoft* @date 2023-08-10*/
public class WeatherConstant {/*** 天气接口地址*/public static final String WEATHER_URL = "";/*** 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";
}
package com.qiangesoft.stant;/*** 天气** @author qiangesoft* @date 2023-08-11*/
public enum WeatherType {/*** * 可参考高德天气对照表*//*** 雪*/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) {de = 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())) {Code();}}return "";}
}
package com.qiangesoft.del;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;/*** 详细天气信息*/@Datapublic 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.qiangesoft.del;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.qiangesoft.del;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.qiangesoft.weather.gaode;/*** 高德API** @author qiangesoft* @date 2023-07-18*/
public class GaoDeApi {/*** 成功标志*/public static final String SUCCESS = "1";/*** 请求key* <p>* 可以申请自己的key:*/public static final String KEY_VALUE = "eea81fd695ceeda7bdab6d3e98ecc2ed";
}
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) {de = 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 == Code();}
}

三、源码仓库

源码地址:

本文发布于:2024-01-28 01:29:57,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063766053851.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23