实现异步天气数据获取与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; @Autowired public 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 weatherMap = new HashMap(); // 获取客户端IP地址 String ip = IpParseUtil.getIpAddr(request); List address = IpParseUtil.parse(ip, null); String region = ""; if (address.size() > 3) { region = address.get(2) + address.get(3); } // 地理位置编码 Map ipInfoMap = restTemplate.getForObject("https://restapi.amap.com/v3/geocode/geo?key=" + GAO_DE_KEY + "&output=json&address=" + region, Map.class); List geocodes = (List) ipInfoMap.get("geocodes"); String adCode = (String) ((LinkedHashMap) geocodes.get(0)).get("adcode"); // 查询天气信息 Map 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 weatherMapResponse, HashMap 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 forecasts = (List) weatherMapResponse.get("forecasts"); String city = forecasts.get(0).get("city").toString().replaceAll("市$", ""); weatherMap.put("city", city); // 实时天气 Map liveWeather = (Map) 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 forecast = (List) 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应用中实现异步天气数据获取并利用缓存来优化性能。这不仅可以提升用户体验,还能降低服务器负载,提高应用的整体效率。
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。