开始天气系统的搭建了
两个个天气API
http://wthrcdn.etouch.cn/weather_mini?citykey=101280101 通过城市id获取天气
http://wthrcdn.etouch.cn/weather_mini?city=广州 通过城市名获取天气
创建WeatherController
package cn.zzu.spring.cloud.weather.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.zzu.spring.cloud.weather.service.WeatherDataService;
import cn.zzu.spring.cloud.weather.vo.WeatherResponse;
/**
* Weather Controller.
*
*/
@RestController
@RequestMapping("/weather")
public class WeatherController {
@Autowired
private WeatherDataService weatherDataService;
@GetMapping("/cityId/{cityId}")
public WeatherResponse getWeatherByCityId(@PathVariable("cityId") String cityId) {
return weatherDataService.getDataByCityId(cityId);
}
@GetMapping("/cityName/{cityName}")
public WeatherResponse getWeatherByCityName(@PathVariable("cityName") String cityName) {
return weatherDataService.getDataByCityName(cityName);
}
}
里面两个方法分别是用id和城市名获取天气 由于是调用WeatherDataService
创建WeatherDataService接口
package cn.zzu.spring.cloud.weather.service;
import cn.zzu.spring.cloud.weather.vo.WeatherResponse;
/**
* Weather Data Service.
*
*/
public interface WeatherDataService {
/**
* 根据城市ID查询天气数据
*
* @param cityId
* @return
*/
WeatherResponse getDataByCityId(String cityId);
/**
* 根据城市名称查询天气数据
*
* @param cityId
* @return
*/
WeatherResponse getDataByCityName(String cityName);
/**
* 根据城市ID来同步天气
* @param cityId
*/
void syncDateByCityId(String cityId);
}
以及它的实现类
package cn.zzu.spring.cloud.weather.service;
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 cn.zzu.spring.cloud.weather.vo.WeatherResponse;
/**
* WeatherDataService 实现.
*
https://www.cnblogs.com/conswin/p/6995631.html redis相关
*/
@Service
public class WeatherDataServiceImpl implements WeatherDataService {
private final static Logger logger = LoggerFactory.getLogger(WeatherDataServiceImpl.class);
private static final String WEATHER_URI = "http://wthrcdn.etouch.cn/weather_mini?";
private static final long TIME_OUT = 1800L; // 1800s
@Autowired
private RestTemplate restTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate; //操作redis
@Override
public WeatherResponse getDataByCityId(String cityId) {
String uri = WEATHER_URI + "citykey=" + cityId;
return this.doGetWeahter(uri);
}
@Override
public WeatherResponse getDataByCityName(String cityName) {
String uri = WEATHER_URI + "city=" + cityName;
return this.doGetWeahter(uri);
}
private WeatherResponse doGetWeahter(String uri) {
String key = uri;
String strBody = null;
ObjectMapper mapper = new ObjectMapper();
WeatherResponse resp = null;
ValueOperations<String, String> redisUtil = stringRedisTemplate.opsForValue();
// 先查缓存,缓存有的取缓存中的数据
if (stringRedisTemplate.hasKey(key)) {
logger.info("Redis has data");
strBody = redisUtil.get(key);
} else {
logger.info("Redis don't has data");
// 缓存没有,再调用服务接口来获取
ResponseEntity<String> respString = restTemplate.getForEntity(uri, String.class);
if (respString.getStatusCodeValue() == 200) {
strBody = respString.getBody();
}
// 数据写入缓存
redisUtil.set(key, strBody, TIME_OUT, TimeUnit.SECONDS);
}
try {
resp = mapper.readValue(strBody, WeatherResponse.class);
} catch (IOException e) {
//e.printStackTrace();
logger.error("Error!",e);
}
return resp;
}
@Override
public void syncDateByCityId(String cityId) {
String uri = WEATHER_URI + "citykey=" + cityId;
this.saveWeatherData(uri);
}
/**
* 把天气数据放在缓存
* @param uri
*/
private void saveWeatherData(String uri) {
String key = uri;
String strBody = null;
ValueOperations<String, String> redisUtil = stringRedisTemplate.opsForValue();
// 调用服务接口来获取
ResponseEntity<String> respString = restTemplate.getForEntity(uri, String.class);
if (respString.getStatusCodeValue() == 200) {
strBody = respString.getBody();
}
// 数据写入缓存
redisUtil.set(key, strBody, TIME_OUT, TimeUnit.SECONDS);
}
}
由于使用到redis做缓存 每次数据先去查取redis 若不存在去接口调用API 所以需要添加redis的依赖
// 依赖关系
dependencies {
// 该依赖用于编译阶段
compile('org.springframework.boot:spring-boot-starter-web')
// HttpClient
compile('org.apache.httpcomponents:httpclient:4.5.3')
// Redis
compile('org.springframework.boot:spring-boot-starter-data-redis')
// 该依赖用于测试阶段
testCompile('org.springframework.boot:spring-boot-starter-test')
}
这样 就实现了半小时数据的更新
贴一下vo类
package cn.zzu.spring.cloud.weather.vo;
import java.io.Serializable;
/**
* Weather Response.
*
*/
public class WeatherResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Weather data;
private Integer status;
private String desc;
public Weather getData() {
return data;
}
public void setData(Weather data) {
this.data = data;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
import java.io.Serializable;
import java.util.List;
/**
* 天气信息.
*
*/
public class Weather implements Serializable {
private static final long serialVersionUID = 1L;
private String city;
private String aqi;
private String ganmao;
private String wendu;
private Yeaterday yesterday;
private List<Forecast> forecast;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getAqi() {
return aqi;
}
public void setAqi(String aqi) {
this.aqi = aqi;
}
public String getGanmao() {
return ganmao;
}
public void setGanmao(String ganmao) {
this.ganmao = ganmao;
}
public String getWendu() {
return wendu;
}
public void setWendu(String wendu) {
this.wendu = wendu;
}
public Yeaterday getYesterday() {
return yesterday;
}
public void setYesterday(Yeaterday yesterday) {
this.yesterday = yesterday;
}
public List<Forecast> getForecast() {
return forecast;
}
public void setForecast(List<Forecast> forecast) {
this.forecast = forecast;
}
}
import java.io.Serializable;
/**
* 未来天气.
*
*/
public class Forecast implements Serializable {
private static final long serialVersionUID = 1L;
private String date;
private String high;
private String fengli;
private String low;
private String fengxiang;
private String type;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getHigh() {
return high;
}
public void setHigh(String high) {
this.high = high;
}
public String getFengli() {
return fengli;
}
public void setFengli(String fengli) {
this.fengli = fengli;
}
public String getLow() {
return low;
}
public void setLow(String low) {
this.low = low;
}
public String getFengxiang() {
return fengxiang;
}
public void setFengxiang(String fengxiang) {
this.fengxiang = fengxiang;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
import java.io.Serializable;
/**
* 昨日天气.
*
*/
public class Yeaterday implements Serializable {
private static final long serialVersionUID = 1L;
private String date;
private String high;
private String fx;
private String low;
private String fl;
private String type;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getHigh() {
return high;
}
public void setHigh(String high) {
this.high = high;
}
public String getFx() {
return fx;
}
public void setFx(String fx) {
this.fx = fx;
}
public String getLow() {
return low;
}
public void setLow(String low) {
this.low = low;
}
public String getFl() {
return fl;
}
public void setFl(String fl) {
this.fl = fl;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
该实体类数据结构的实现 可以先去访问API 对获得的json格式数据进行分析
好了 到这里 天气系统就写好了 并且做到了半小时数据的更新
测试一下