欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Spring Boot实现一个天气预报系统(一)

发布时间:2025/3/20 45 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Spring Boot实现一个天气预报系统(一) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1.数据来源

  • 天气的数据来源为中华万年历

    通过城市名称获得天气数据:http://wthrcdn.etouch.cn/weather_mini?city=北京

    通过城市id获得天气数据:http://wthrcdn.etouch.cn/weather_mini?citykey=101280601

  • 城市id列表

    每个城市都有一个唯一的id作为标识:https://waylau.com/data/citylist.xml

  • 这里已北京为例,可以看到如下天气数据返回

{"data": {"yesterday": {"date": "26日星期三","high": "高温 35℃","fx": "南风","low": "低温 23℃","fl": "<![CDATA[3-4级]]>","type": "多云"},"city": "北京","forecast": [{"date": "27日星期四","high": "高温 33℃","fengli": "<![CDATA[<3级]]>","low": "低温 23℃","fengxiang": "北风","type": "多云"}, {"date": "28日星期五","high": "高温 33℃","fengli": "<![CDATA[<3级]]>","low": "低温 23℃","fengxiang": "南风","type": "多云"}, {"date": "29日星期六","high": "高温 36℃","fengli": "<![CDATA[<3级]]>","low": "低温 23℃","fengxiang": "东风","type": "多云"}, {"date": "30日星期天","high": "高温 32℃","fengli": "<![CDATA[3-4级]]>","low": "低温 22℃","fengxiang": "北风","type": "多云"}, {"date": "1日星期一","high": "高温 34℃","fengli": "<![CDATA[<3级]]>","low": "低温 23℃","fengxiang": "北风","type": "晴"}],"ganmao": "各项气象条件适宜,发生感冒机率较低。但请避免长期处于空调房间中,以防感冒。","wendu": "29"},"status": 1000,"desc": "OK" }

2.开发环境

  • JDK8

  • Maven

  • Spring Boot Web Starter 2.1.6

  • Apache HttpClient 4.5.3

3.初始化一个Spring Boot项目

(1)添加maven依赖

       <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.0</version><scope>provided</scope></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.3</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency> ​<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.1.7.RELEASE</version><scope>compile</scope></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.8</version><scope>compile</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

(2)创建实体类

@Data public class Weather implements Serializable {private String city;private String aqi;private String wendu;private String ganmao;private Yesterday yesterday;private List<Forecast> forecast; } @Data public class Forecast implements Serializable {private String date;private String high;private String fengxiang;private String low;private String fengli;private String type; } @Data public class Yesterday implements Serializable {private String date;private String high;private String fx;private String low;private String fl;private String type; } @Data public class WeatherResponse implements Serializable {/*** 消息数据*/private Weather data;/*** 消息状态*/private String status;/*** 消息描述*/private String desc; }

(3)服务接口及实现

public interface WeatherDataService { ​/*** 根据城市id来查询天气数据** @param cityId* @return*/WeatherResponse getDataByCityId(String cityId); ​/*** 根据城市名称来查询天气数据** @param cityName* @return*/WeatherResponse getDataByCityName(String cityName); } @Service public class WeatherDataServiceImpl implements WeatherDataService {@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate StringRedisTemplate stringRedisTemplate;private final Logger logger = LoggerFactory.getLogger(WeatherDataServiceImpl.class);private final String WEATHER_API = "http://wthrcdn.etouch.cn/weather_mini";/*** 缓存超时时间*/private final Long TIME_OUT = 1800L; ​@Overridepublic WeatherResponse getDataByCityId(String cityId) {String uri = WEATHER_API + "?citykey=" + cityId;return this.doGetWeatherData(uri);} ​@Overridepublic WeatherResponse getDataByCityName(String cityName) {String uri = WEATHER_API + "?city=" + cityName;return this.doGetWeatherData(uri);} ​private WeatherResponse doGetWeatherData(String uri) {ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();//将调用的uri作为缓存的keyString strBody = null;//先查缓存,没有找到查服务if (!stringRedisTemplate.hasKey(uri)) {logger.info("未找到 key " + uri); ​ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);if (response.getStatusCodeValue() == 200) {strBody = response.getBody();}ops.set(uri, strBody, TIME_OUT, TimeUnit.SECONDS);} else {logger.info("找到 key " + uri + ",value=" + ops.get(uri));strBody = ops.get(uri);}ObjectMapper mapper = new ObjectMapper();WeatherResponse weather = null;try {weather = mapper.readValue(strBody, WeatherResponse.class);} catch (IOException e) {e.printStackTrace();}return weather;} }

(4)控制层类

@RestController @RequestMapping("/weather") public class WeatherController {@Autowiredprivate WeatherDataService weatherDataService; ​@GetMapping("/cityId/{cityId}")public WeatherResponse getReportByCityId(@PathVariable("cityId") String cityId) {return weatherDataService.getDataByCityId(cityId);} ​@GetMapping("/cityName/{cityName}")public WeatherResponse getReportByCityName(@PathVariable("cityName") String cityName) {return weatherDataService.getDataByCityName(cityName);} }

(5)配置类

@Configuration public class Config {@Beanpublic RestTemplate restTemplate(RestTemplateBuilder builder) {// Do any additional configuration herereturn builder.build();} }

(6)Spring配置文件

spring:redis:host: 127.0.0.1database: 0password:port: 6379

4.为什么使用Redis

缓存的使用与系统的时效性有着非常大的关系。当所使用的系统时效性要求不高时,选择使用缓存是极好的。当系统要求的时效性比较高时,则并不适合使用缓存。

天气数据接口,本身时效性并不是很高,而且又因为时Web服务,在调用过程中,是存在延时的。所以,采用缓存,一方面可以有效减轻访问天气接口服务带来的延时问题;另一方面也可以减轻天气接口的负担,提高并发访问量。

特别是使用第三方免费的天气API,这些API往往对用户的调用次数及频率有一定的限制。所以为了减轻天气API提供方的负荷,并不需要去实时调用其第三方接口。

由于天气数据更新频率的特点(基本上一个小时或半个小时更新一次),因此,在redis中设置了30分钟的失效时间。

5.测试和运行

1.启动Spring Boot项目,启动redis

2.访问接口:http://localhost:8080/weather/cityName/太原,日志如下

未找到 key http://wthrcdn.etouch.cn/weather_mini?city=太原

3.再次访问上面的接口,日志如下

找到 key http://wthrcdn.etouch.cn/weather_mini?city=太原,value={"data":{"yesterday":{"date":"26日星期三","high":"高温 32℃","fx":"东北风","low":"低温 20℃","fl":"<![CDATA[<3级]]>","type":"多云"},"city":"太原","forecast":[{"date":"27日星期四","high":"高温 28℃","fengli":"<![CDATA[<3级]]>","low":"低温 18℃","fengxiang":"北风","type":"小雨"},{"date":"28日星期五","high":"高温 32℃","fengli":"<![CDATA[<3级]]>","low":"低温 16℃","fengxiang":"东北风","type":"多云"},{"date":"29日星期六","high":"高温 32℃","fengli":"<![CDATA[<3级]]>","low":"低温 15℃","fengxiang":"西北风","type":"晴"},{"date":"30日星期天","high":"高温 30℃","fengli":"<![CDATA[<3级]]>","low":"低温 16℃","fengxiang":"北风","type":"晴"},{"date":"1日星期一","high":"高温 31℃","fengli":"<![CDATA[<3级]]>","low":"低温 15℃","fengxiang":"东南风","type":"多云"}],"ganmao":"相对今天出现了较大幅度降温,较易发生感冒,体质较弱的朋友请注意适当防护。","wendu":"27"},"status":1000,"desc":"OK"}

 

 

总结

以上是生活随笔为你收集整理的Spring Boot实现一个天气预报系统(一)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。