从天气项目看 Spring Cloud 微服务治理| |单体项目搭建
一个单体结构天气预报系统
天气数据来源:http://wthrcdn.etouch.cn/weather_mini?citykey=城市的ID
这个天气气预报系统的功能模块分为以下:
1、获取城市天气数据(需要城市ID来查询相应的城市天气)
2、获取城市ID
3、定时同步天气数据,同步的天气数据时需要查询出相应的城市ID,然后根据城市ID查询出天气数据进行同步
4、展示天气数据,依赖于城市ID数据和天气数据
接下来用代码介绍一下这个项目整体的流程:
项目环境:上一章节已经设计,这一章节不在赘述
1、创建项目:micro-weather-report**
2、写各个业务逻辑:
- 获取天气数据数据
通过HttpClient客户端直接可以获取第三方天气数据,引入如下:
@Autowired
private RestTemplate restTemplate;
其依赖:
//HttpClient
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.9'
注意两点:
1、查询可以通过城市名称来查询天气数据,也可以根据城市ID来查询天气数据。
2、查询天气数据时之前先从缓存中查询,如果缓存中没有,则通过第三方数据查询
public interface WeatherDataService {
/**
* 根据城市ID查询天气数据
* @param cityId
* @return
*/
WeatherResponse getDataByCityId(String cityId);
/**
* 根据城市名称查询天气数据
* @param cityName
* @return
*/
WeatherResponse getDataByCityName(String cityName);
/**
* 根据城市Id来同步天气
* @param cityId
*/
void syncDateByCityId(String cityId);
}
对于缓存,这里是通过Redis接口来操作NoSQL数据库:
其依赖:
//redis
compile group: 'org.springframework.boot', name:'spring-boot-starter-data-redis',version: '2.0.4.RELEASE'
@Autowired
private StringRedisTemplate stringRedisTemplate;
2、查询出数据之后需要对数据进行反序列化,通过工具类ObjectMapper将String数据转换成json字符串所以对于需要映射到的实体对象类,都实现了Serializable接口,而且添加了注解
@JsonIgnoreProperties(ignoreUnknown = true)
public class WeatherResponse implements Serializable {
private static final long serialVersionUID = 1L;
private Weather data;
private Integer status;
private String desc;
}
做到这块就是因为总是把报反序列化错误,所以可以参考我的这篇博客:
字符串反序列化
3、当查询出天气数据后,需要将天气数据同步到缓存中,但需要根据相应的城市ID来查询出天气数据,接着定义了Job起到定时与调度的作用,并引入天气数据和城市ID数据
同步到缓存时,通过使用Quartz任务调度器来实现实时对数据进行同步
其Quartz依赖
//Quartz
compile group: 'org.springframework.boot', name:'spring-boot-starter-quartz',version: '2.0.4.RELEASE'
同步到缓存前我们也查询了城市ID,因为同步天气数据需要相应的城市ID,我们从本地的XML文件中读取城市的ID,将XML转换为指定的pojo对象,工具类代码如下:
public class XmlBuilder {
/***
*
* 将xml转为指定的pojo对象
* @param clazz
* @param xmlStr
* @return
* @throws Exception
*/
public static Object xmlStrToObject(Class<?> clazz,String xmlStr)throws Exception{
Object xmlObject=null;
Reader reader=null;
JAXBContext context=JAXBContext.newInstance(clazz);
//XML转为对象的接口
Unmarshaller unmarshaller=context.createUnmarshaller();
reader=new StringReader(xmlStr);
xmlObject=unmarshaller.unmarshal(reader);
if(null!=reader){
reader.close();
}
return xmlObject;
}
}
随后进行同步数据,通过一个自定义job类来实现,这个类继承了QuartzJobBean,代码如下:
public class WeatherDataSynJob extends QuartzJobBean {
@Autowired
private CityDataService cityDataService;
@Autowired
private WeatherDataService weatherDataService;
private final static Logger logger= LoggerFactory.getLogger(WeatherDataSynJob.class);
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
logger.info("Weather Data Syn Job start!");
//获取城市ID列表
List<City> cityList=null;
try{
cityList=cityDataService.listCity();
}catch (Exception e){
logger.error("Exception!",e);
}
//遍历城市ID获取天气
for(City city:cityList){
String cityId=city.getCityId();
logger.info("Weather Data sync Job,cityId : "+cityId);
weatherDataService.syncDateByCityId(cityId);
}
logger.info("Weather Data Sync Job End!");
}
}
接下来就同步BootStrap和模板技术Thymeleaf来实现数据的展示,其依赖
//添加Springboot Thymeleaf Starter的依赖
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf
compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
项目整体环境依赖如下build.gradle文件:
plugins {
id 'java'
id 'war'
}
group 'pers.chao'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
//buildscript 代码块中脚本优先执行
buildscript{
extensions{
springBootVersion = '2.0.0.M4'
}
repositories {
maven{ url "http://maven.aliyun.com/nexus/content/groups/public/"}
}
dependencies{
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
repositories {
maven{ url "http://maven.aliyun.com/nexus/content/groups/public/"}
}
dependencies {
//springboot
compile group: 'org.springframework.boot', name:'spring-boot-starter-web',version: '2.0.4.RELEASE'
testCompile group: 'org.springframework.boot', name:'spring-boot-starter-test',version: '2.0.4.RELEASE'
//redis
compile group: 'org.springframework.boot', name:'spring-boot-starter-data-redis',version: '2.0.4.RELEASE'
//HttpClient
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.9'
//Quartz
compile group: 'org.springframework.boot', name:'spring-boot-starter-quartz',version: '2.0.4.RELEASE'
//添加Springboot Thymeleaf Starter的依赖
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf
compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
testCompile group: 'junit', name: 'junit', version: '4.11'
testCompile group: 'junit', name: 'junit', version: '4.12'
}