实现异步天气数据获取与Spring缓存集成

你好呀,我是小邹。

在Web应用中,实时天气数据的获取是一个常见的需求,特别是在需要频繁更新天气信息的场景下,如旅游网站、天气应用或任何需要展示地理位置相关天气的应用。然而,频繁的外部API调用不仅会增加服务器的负担,还可能导致网络延迟,影响用户体验。为了优化这一过程,本文将介绍如何在Spring Boot应用中利用异步调用和缓存技术来高效地获取并存储天气数据。

效果图

在这里插入图片描述

引入Spring异步支持

在Spring框架中,可以使用@Async注解来指定方法应该异步执行。这允许应用在等待耗时操作(如网络调用)完成的同时继续处理其他请求,从而提高了整体的响应性和吞吐量。

利用Spring Cache缓存结果

为了减少对远程API的重复调用,我们可以使用Spring Cache框架来缓存天气数据。@Cacheable注解可以自动存储方法的返回值,如果下次请求相同的数据,它将从缓存中读取,而不是重新执行方法。

代码实现

以下代码示例展示了如何在Spring Boot中结合使用@Async@Cacheable注解来异步获取并缓存天气数据:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.data.util.Pair;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.collection.CollUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;@Service
public class WeatherService {private static final String WEATHER_CACHE_NAME = "weatherCache";private static final String GAO_DE_KEY = "YOUR_GAODE_API_KEY";private final RestTemplate restTemplate;@Autowiredpublic WeatherService(RestTemplate restTemplate) {this.restTemplate = restTemplate;}@Async@Cacheable(value = WEATHER_CACHE_NAME, key = "'todayWeather'")public void getWeather(Model model) {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();HashMap<String, String> weatherMap = new HashMap<>();// 获取客户端IP地址String ip = IpParseUtil.getIpAddr(request);List<String> address = IpParseUtil.parse(ip, null);String region = "";if (address.size() > 3) {region = address.get(2) + address.get(3);}// 地理位置编码Map<String, Object> ipInfoMap = restTemplate.getForObject("https://restapi.amap.com/v3/geocode/geo?key=" + GAO_DE_KEY + "&output=json&address=" + region, Map.class);List<Object> geocodes = (List<Object>) ipInfoMap.get("geocodes");String adCode = (String) ((LinkedHashMap) geocodes.get(0)).get("adcode");// 查询天气信息Map<String, Object> weatherMapResponse = restTemplate.getForObject("https://restapi.amap.com/v3/weather/weatherInfo?city=" + adCode + "&key=" + GAO_DE_KEY + "&extensions=all", Map.class);// 处理天气信息processWeatherResponse(weatherMapResponse, weatherMap);// 将天气数据添加到模型中model.addAttribute("weather", weatherMap);}private void processWeatherResponse(Map<String, Object> weatherMapResponse, HashMap<String, String> weatherMap) {if (CollUtil.isEmpty((Collection<?>) weatherMapResponse.get("forecasts"))) {// 如果无法获取天气信息,设置默认值weatherMap.put("city", "获取定位失败");weatherMap.put("weather", "*");weatherMap.put("temperature", "*");weatherMap.put("reportTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));weatherMap.put("tomorrowWeather", "*");weatherMap.put("tomorrowTemperature", "*");weatherMap.put("tomorrowLowTemperature", "*");} else {// 提取并处理天气信息List<Map<String, Object>> forecasts = (List<Map<String, Object>>) weatherMapResponse.get("forecasts");String city = forecasts.get(0).get("city").toString().replaceAll("市$", "");weatherMap.put("city", city);// 实时天气Map<String, Object> liveWeather = (Map<String, Object>) forecasts.get(0).get("lives");weatherMap.put("weather", (String) liveWeather.get("weather"));weatherMap.put("temperature", (String) liveWeather.get("temperature"));weatherMap.put("reportTime", (String) liveWeather.get("reporttime"));// 天气预报List<Map<String, Object>> forecast = (List<Map<String, Object>>) forecasts.get(0).get("casts");weatherMap.put("tomorrowWeather", (String) forecast.get(1).get("dayweather"));weatherMap.put("tomorrowTemperature", (String) forecast.get(1).get("daytemp"));weatherMap.put("tomorrowLowTemperature", (String) forecast.get(1).get("nighttemp"));}}
}
注意事项
  • 以上代码示例中,IpParseUtil是一个自定义的工具类,用于解析IP地址并获取地理位置信息。你需要根据实际情况实现或替换这部分逻辑。
  • GAO_DE_KEY应该替换为你的高德地图API密钥。
  • RestTemplate用于发起HTTP请求,你可以选择使用WebClient或任何其他HTTP客户端库作为替代。
  • 确保你的Spring Boot项目中已经包含了Spring Cache和Spring Web的支持。

通过以上步骤,你可以在Spring Boot应用中实现异步天气数据获取并利用缓存来优化性能。这不仅可以提升用户体验,还能降低服务器负载,提高应用的整体效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/379901.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go网络编程-RPC程序设计

gRPC 通信 RPC 介绍 RPC, Remote Procedure Call&#xff0c;远程过程调用。与 HTTP 一致&#xff0c;也是应用层协议。该协议的目标是实现&#xff1a;调用远程过程&#xff08;方法、函数&#xff09;就如调用本地方法一致。 如图所示&#xff1a; 说明&#xff1a; Servi…

生活中生智慧

【 圣人多过 小人无过 】 觉得自己做得不够才能做得更好&#xff0c;互相成全&#xff1b;反求诸己是致良知的第一步&#xff1b;有苦难才能超越自己&#xff0c;开胸怀和智慧&#xff1b;不浪费任何一次困苦&#xff0c;危机中寻找智慧&#xff0c;成长自己。 把困苦当作当下…

WINUI或WPF灵活使用样式、控件模板、自定义控件、用户控件

在WINUI与WPF 中&#xff0c;控件模板&#xff08;ControlTemplate&#xff09;、样式&#xff08;Style&#xff09;、自定义控件&#xff08;CustomControl&#xff09;和用户控件&#xff08;UserControl&#xff09;都是构建复杂和灵活用户界面的重要工具&#xff0c;但它们…

SpringCloudAlibaba-Seata2.0.0与Nacos2.2.1

一、下载 ## 下载seata wget https://github.com/apache/incubator-seata/releases/download/v2.0.0/seata-server-2.0.0.tar.gz## 解压 tar zxvf seata-server-2.0.0.tar.gz二、执行sql文件 ## 取出sql文件执行 cd /seata/script/server/db/mysql ## 找个mysql数据库执行三、…

java文本比较解决方案

参考资料 VBA计算页码和行号https://learn.microsoft.com/zh-cn/office/vba/api/word.wdinformation 概述&#xff1a; 最近在做word文档对比的&#xff0c;总结了几种解决方案&#xff0c;记录一下 在java中&#xff0c;常用的文本对比方案有如下几种&#xff1a; 差异比较…

数据结构--二叉树收尾

目录 1.二叉树的销毁 2.层序遍历 2.1深度优先搜索 2.1.1满&#xff08;完全&#xff09;二叉树引入 2.1.2什么是广度优先搜索 2.2广度优先搜索 2.2.1基本思路 2.2.2代码解析 3.完全二叉树的判断 3.1思路分析 3.2原理剖析 3.3代码分析 4.逆推二叉树结构 1.二叉树的销…

惠海H5112A降压恒流芯片IC 60V72V80V100V转24V36V48V多路共阳输出景观LED点光源

H5112A是一款外围电路简单的多功能平均电流型LED恒流驱动器&#xff0c;适用于5-90V电压范围的非隔离式大功率恒流LED驱动领域。芯片采用了平均电流模式控制&#xff0c;输出电流精度在士3%;输出电流对输入输出电压以及电感不敏感;芯片内部集成了环路补偿&#xff0c;外围电路更…

网络编程-TCP 协议的三次握手和四次挥手做了什么

TCP 协议概述 1. TCP 协议简介 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP 协议提供可靠的通信服务&#xff0c;通过校验和、序列号、确认应答、重传等机制保证数据传输…

自动化测试高级控件交互方法:TouchAction、触屏操作、点按,双击,滑动,手势解锁!

在自动化测试领域中&#xff0c;TouchAction 是一种非常强大的工具&#xff0c;它允许我们模拟用户在设备屏幕上的各种触摸事件。这种模拟不仅限于简单的点击操作&#xff0c;还包括滑动、长按、多点触控等复杂的手势。 点按与双击 点按和双击是触屏设备上最基本的操作之一。…

【AMD/Xilinx】FPGA远程烧录调试工具安装及使用

问题描述 在学习工作中&#xff0c;本人遇到了连接FPGA的服务器电脑没有Vivado或Vivado版本较低&#xff0c;导致没办法查看ila的情况。在这种情况下一方面重新安装Vivado需要占用大量存储空间&#xff0c;另一方面使用远程桌面软件连接服务器电脑的画质较为模糊&#xff0c;影…

走进数组的奇妙之旅

引言&#xff1a; 在前几篇文章中&#xff0c;我们深入探讨了函数的奥秘。在讲述函数知识的过程中&#xff0c;我们邂逅了一个新的概念&#xff0c;你或许还记得在演示 strcpy函数时&#xff0c;出现的这行代码&#xff1a;char1[20]{0};。当时&#xff0c;你是否感到好奇&…

PHP萌宠之家微信小程序系统源码

&#x1f43e;萌宠之家微信小程序&#x1f43e; —— 铲屎官们的温馨小窝✨ &#x1f3e0;【一键开启萌宠乐园】&#x1f3e0; 亲们&#xff0c;是不是每次刷手机都忍不住想看看那些软萌可爱的毛孩子&#xff1f;现在&#xff0c;有了“萌宠之家”微信小程序&#xff0c;你的…

通信流程:https【SSL/TLS】,git仓库【https/SSH】,蓝牙【面对面快传/AirDrop】

目录 HTTPS HTTP&#xff08;80端口&#xff09; SSL/TLS协议&#xff08;传输层&#xff0c;443端口&#xff09; 密文传输&#xff1a;SSL的后续版本TLS TLS1.2握手 1.摘要算法(散列函数 Hash Function)&#xff1a;验证信息的完整性&#xff0c;不可逆 第三方认证 引…

数据结构之初始二叉树(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 二叉树的前置知识&#xff08;概念、性质、、遍历&#xff09; 通过上篇文章的学习&#xff0c;我们…

iOS——MRC与ARC以及自动释放池深入底层学习

MRC与ARC再回顾 在前面&#xff0c;我们简单学了MRC与ARC。MRC指手动内存管理&#xff0c;需要开发者使用retain、release等手动管理对象的引用计数&#xff0c;确保对象在必要时被释放。ARC指自动内存管理&#xff0c;由编译器自动管理对象的引用计数&#xff0c;开发者不需要…

如何用EXCEL自动解方程/方程组?利用 矩阵乘法X=A-*B,X=mmult(minverse(A), B)

目录 问题的由来 1 数据 → 模拟分析 → 单变量求解 1.1 找一个单元格填入公式 1.2 功能入口 1.3 选择单变量求解&#xff0c;分别填入内容 1.4 求解 1.5 这个感觉用处不大 2 重点介绍&#xff0c;用EXCEL进行矩阵运算解方程的操作 2.1 运用EXCEL进行矩阵运算&…

Sentinel-1 Level 1数据处理的详细算法定义(四)

《Sentinel-1 Level 1数据处理的详细算法定义》文档定义和描述了Sentinel-1实现的Level 1处理算法和方程,以便生成Level 1产品。这些算法适用于Sentinel-1的Stripmap、Interferometric Wide-swath (IW)、Extra-wide-swath (EW)和Wave模式。 今天介绍的内容如下: Sentinel-1 L…

操作系统内核源码杂谈篇:临界区

临界资源&#xff0c;是指同一时刻只能由一个线程&#xff08;linux下为进程&#xff09;访问的资源&#xff0c;而临界区就是为了确保临界资源访问是单一数据流。 临界区的代码执行&#xff0c;也就是进行原子操作&#xff0c;不会被打断。 先分析RTOS的运行架构&#xff0c…

人工智能算法工程师(高级)课程1-单类目标识别之人脸检测识别技术MTCNN模型介绍与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(高级)课程1-单类目标识别之人脸检测识别技术MTCNN模型介绍与代码详解。本文深入探讨了基于PyTorch的人脸检测与识别技术&#xff0c;详细介绍了MTCNN模型、Siamese network以及center loss、sof…

qml 实现一个listview

主要通过qml实现listvie功能&#xff0c;主要包括右键菜单&#xff0c;滚动条&#xff0c;拖动改变内容等&#xff0c;c 与 qml之间的变量和函数的调用。 main.cpp #include <QQuickItem> #include <QQmlContext> #include "testlistmodel.h" int main…