springcloud微服务实践:天气数据API微服务的实现

2022-10-28 15:52:42 浏览数 (1)

天气数据API 微服务的实现

天气数据API微服务包含了天气数据查询组件。天气数据查询组件提供了天气数据查询的接口。

我们的数据已经通过天气数据采集微服务集成到了Redis 存储中,天气数据API微服务只需要从Redis获取数据,而后从接口中暴露出去即可。

在micro-weather-report应用的基础上,我们将对其进行逐步的拆分,形成一个新的微服务msa-weather-data-server应用。

所需环境

为了演示本例子,需要采用如下开发环境。

  • JDK 8。
  • Gradle 4.0。
  • Spring Boot Web Starter 2.0.0.M4。
  • Spring Boot Data Redis Starter 2.0.0.M4。
  • Redis 3.2.100。

修改天气数据服务接口及实现

在com.waylau.spring.cloud. weather.service包下,我们之前已经定义了该应用的天气数据服务接口WeatherDataService。

代码语言:javascript复制
public interface WeatherDataService {
*★
*根据城市ID查询天气数据
@param cityId
@return 
WeatherResponse getDataByCityId(String cityId);
/**
★根据城市名称查询天气数据
* @param cityId
* Creturn
*/
Wea therResponse getDataByCityName (String cityName) ;
}

对于该微服务而言,我们并不需要同步天气的业务需求,所以把之前定义的syncDataByCityId方法删除了。

WeatherDataServicelmpl是对WeatherDataService 接口的实现,也要做出相应的调整,将同步天气的代码逻辑都删除,保留以下代码。

代码语言:javascript复制
package com. way1au . spr ing.cloud.weather .service;
import java. io. IOException;
import org.slf4j . Logger;
import org.slf4j. LoggerFactory;
import org.springf ramework. beans. factory . annotation.Autowired;
import org. springfr amework. data. redis. core. StringRedisTemplate;
import org. springf ramework. data. redis.core. ValueOperations;
import org. springf ramework. stereotype. Service;
import com. fasterxml. jackson.databind. objectMapper;
import com. waylau. spring. cloud . weather . vo . Wea therResponse;
/**
k天气数据服务.
@since 1.0.0 2017年10月29日 
* @author <a href="https:/ /waylau.com">Way Lau</a>
@Service
public class WeatherDataServiceImpl implements WeatherDataService {
private final static Logger logger = LoggerFactory .getLogger (Weather
DataServiceImpl.class) ;
@Autowi red
private StringRedisTemplate stringRedisTemplate; 
private final String WEATHER API = "http://wthrcdn. etouch . cn/weather_
mini";
@Override
public WeatherResponse getDa taByCityId(String cityId) {
String uri = WEATHER API   "?citykey="   cityId;
return this. doGetWea therData (uri) ;
@Override
public WeatherResponse getDataByCityName (String cityName) {
String uri = WEATHER_ API   "?city="   cityName ;
return this. doGe tWeatherData (uri) ;
private WeatherResponse doGetWea therData (String uri)
valueOperations<String, String> ops = this.stringRedisTemplate.
opsForValue() ;
String key = uri;
String strBody = null;
/先查缓存,查不到抛出异常
if (!this. stringRedisTemplate . hasKey (key)) {
logger .error("不存在key "  key) ;
throw new Runt imeException ("没有相应的天气信息") ;
} else {
logger.info("存在key"  key   ", value="   ops.get (key));
strBody = ops.get (key) ;
}
0bj ectMapper mapper = new ObjectMapper () ;
WeatherResponse weather = null;
try {
weather = mapper . readvalue (strBody, WeatherResponse.class) ;
} catch (IOException e) {
logger . error ("JSON反序列化异常! ",e);
throw new RuntimeException ("天气信息解析失败") ;
return weather;
}
}

其中需要注意的是:

●原有的RestTemplate用作REST客户端来进行天气数据的同步,这个类相关的代码都可以删除了;

●服务 会先从缓存中进行查询,查不到数据就抛出异常(有可能该城市的天气数据未同步,或者是数据已经过期) ;

在执行反序列化JSON过程中也可能遭遇异常,同样将异常信息抛出。

除上述WeatherDataServicelmpl、WeatherDataService 外,其他服务层的代码都可以删除了。

调整控制层的代码

除了WeatherController 外,其他控制层的代码都不需要了。

WeatherController仍然是原有的代码保持不变。

代码语言:javascript复制
@RestController
@RequestMapping (" /weather")
public class Wea therController {
@Autowi red 
private 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) ;}
}

删除配置类、天气数据同步任务和工具类

配置类RestConfiguration、QuartzConfiguration 及任务类WeatherDataSyncJob、 工具类Xml-

Builder的代码都可以删除了。

清理值对象

值对象我们需要保留解析天气相关的类即可,其他值对象(如City. CityList等)都可以删除了。

清理前端代码、配置及测试用例

已经删除的服务接口的相关测试用例自然也是要一并 删除的。

同时,之前所编写的页面HTML、JS文件也要一并 删除。

最后,要清理Thymeleaf在application.properties文件中的配置,以及build.gradle文件中的依赖。

Apache HttpClient、Quartz 的依赖也一并删除。

测试和运行

运行应用,通过访问 htp:/ahost:808/weather/cityId/101280601接口来测试。

当Redis中天气数据不存在时,将会有如下信息返回。

代码语言:javascript复制
"timestamp": 1509289762537,
"status": 500,
"error": "Internal Server Error",
"message":” 没有相应的天气信息",
"path": "/weather/cityId/101280601"
当Redis中天气数据存在时,则将返回相应的天气信息。
"data": {
"city": "深圳",
"aqi": "81",
"wendu": "23",
"ganmao": "各项气象条件适宜,无明显降温过程,发生感冒机率较低。",
"yesterday":
"date": "28日 星期六",
"high": "高温29"C",
"fx": "无持续风向",
"low": "低温20°C"
"fI": "<! [CDATA[<3级]]>",
"type": "晴"
},
"forecast": [
"date": "29日 星期天",
"high": "高温27"C",
"fengxiang": "无持续风向",
"low": "低温20C",
"fengli": "<! [CDATA[<3级]]>",
"type": "多云"
"date": "30日 星期一一",
"high": "高温26"C",
"fengxiang": "无持续风向",
"1ow": "低温17C",
"fengli": "<! [CDATA[<3级]]>",
"type": "晴 ”
"date": "31日 星期二",
"high": "高温25"C",
"fengxiang": "无持续风向",
"low": "低温17C",
"fengli": "<! [CDATA[<3级]]>",
"type": "多云"
},
{
"date": "1日星期三",
"high": "高温26"C",
"fengxiang":”无持续风向",
"low": "低温18C",
"fengli": "<! [CDATA[<3级]]>",
"type": "多云"
},
"date": "2 日星期四",
"high": "高温27C",
"fengxiang": "无持续风向",
"low": "低温20C",
"fengli": "<! [CDATA[<3级]]>",
"type": "多云"
},
"status": "1000",
"desc": "OK"}

本篇内容给大家讲解的内容是天气数据API 微服务的实现

  1. 下篇文章给大家讲解天气预报微服务的实现;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!!

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

0 人点赞