在前一章节我们简单做了下查询数据的,但是在实际应用中,这个接口是网上免费的,而且还是web服务,在调用过程中,是存在延时的,所以,一般来说我们采用缓存,一方面可以减轻访问接口带来的延时问题,另一方面,也可以减轻接口的负担,提高并发访问量。
本章节采用redis缓存做一个简答的模拟。
1。在原有项目上,我们在pom.xml中增加坐标
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2。下载并安装redis(针对windos有专门的安装包),下载双击之后出现下面的截图就可以了。
3。修改实现类
package com.yian.springboot.service.Impl;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yian.springboot.service.WeatherDateService;
import com.yian.springboot.vo.WeatherResponse;
@Service
public class WeatherDateServiceImpl implements WeatherDateService{
private final static Logger logger=LoggerFactory.getLogger(WeatherDateServiceImpl.class);
@Autowired
private RestTemplate restTemplate;
//增加StringRedisTemplate ,用于操作redis,
@Autowired
private StringRedisTemplate stringRedisTemplate;
private final String WEATHER_API="http://wthrcdn.etouch.cn/weather_mini";
//设置超时时间
private final Long TIME_OUT=1800L;
@Override
public WeatherResponse getDateByCityId(String cityId) {
String uri=WEATHER_API+"?citykey="+cityId;
return this.doGetWeatherData(uri);
}
@Override
public WeatherResponse getDateByCityName(String cityName) {
String uri=WEATHER_API+"?city="+cityName;
return this.doGetWeatherData(uri);
}
private WeatherResponse doGetWeatherData(String uri) {
ValueOperations<String, String> ops = this.stringRedisTemplate.opsForValue();
String key=uri;//将调用uri设置为缓存中的key
String strBody=null;
//判断缓存中是否有key,如果没有在去查服务
if(!this.stringRedisTemplate.hasKey(key)){
logger.info("未找到缓存的key"+key);
ResponseEntity<String> response=restTemplate.getForEntity(uri, String.class);
if(response.getStatusCodeValue()==200){
strBody=response.getBody();
}
ops.set(key, strBody, TIME_OUT, TimeUnit.SECONDS);
}else{
logger.info("找到缓存的key"+key+",value="+ops.get(key));
strBody=ops.get(key);
}
//jackson库中的类
ObjectMapper mapper= new ObjectMapper();
WeatherResponse weather=null;
try {
//mapper.readValue是将json结构转换成成java对象
//mapper.writeValue是将java对象转成json结构
weather=mapper.readValue(strBody, WeatherResponse.class);
} catch (IOException e) {
logger.error("json反序列化异常", e);
}
return weather;
}
}
关于如何操作redis可看另一篇博客:StringRedisTemplate 操作redis
注意点:
1。在doGetWeatherData方法中增加了redis数据的判断
2。当存在某个key的时候(接口uri是唯一代表某一个地区的天气数据)时候,可以从redis中取缓存数据
3。当不存在某个key的时候(没有初始化数据或者数据过期了)需要重新去uri接口中查询数据,并且初始化到缓存中去。
4。由于天气是有更新的频率的,所以我们可以在redis中设置超时时间,基本上是30分到一个小时左右。
启动项目
访问:http://localhost:8080/weather/cityId/101280603
再次刷新地址栏你会发现: