# 全球新型冠状病毒实时数据统计应用程序的设计与实现 **Repository Path**: xie-hong/experiment-3 ## Basic Information - **Project Name**: 全球新型冠状病毒实时数据统计应用程序的设计与实现 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-11-20 - **Last Updated**: 2021-10-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 东莞理工学院网络空间安全学院 | **课程名称:** | 企业级开发框架专题 | **学期**:2020秋季 | | :----------------- | :-------------------------------------------: | :------------------: | | **实验名称**:实验三 |全球新型冠状病毒实时数据统计应用程序的设计与实现| **实验序号**:三 | | **姓名**:谢泓泓 | **学号**:201841413134 | **班级**:18网工1班 | | **实验地址**:线上 | **实验日期**:2020-11-8 | **指导老师**:黎志雄 | | **教师评语**: | **实验成绩**: | **同组同学**:无 | # 实验三 全球新型冠状病毒实时数据统计应用程序的设计与实现 ### 一、实验目的 >1、 掌握使用Spring框架自带的RestTemplate工具类爬取网络数据; >2、 掌握使用Spring框架自带的计划任务功能; >3、 掌握使用Apache Commons CSV组件解释CSV文件; >4、 掌握Java 8的Stream API处理集合类型数据; >5、 了解使用模板引擎或前端框架展示数据。 ### 二、实验环境 >1、 JDK 1.8或更高版本 >2、 Maven 3.6+ >3、 IntelliJ IDEA >4、 commons-csv 1.8+ ### 三、 实验任务 #### 任务一 > 通过IntelliJ IDEA的Spring Initializr向导创建Spring Boot项目 ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/150418_e67cf436_8031809.png "屏幕截图.png") #### 任务二 > 2、 添加功能模块:spring MVC、lombok、commons-csv等。推荐使用commons-csv组件处理csv文件: ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/150626_4582253c_8031809.png "屏幕截图.png") #### 任务三 > 爬取全球冠状病毒实时统计数据。(Java,Spring) CSV文件地址:https://gitee.com/dgut-sai/COVID-19 ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/152229_c6edbcfc_8031809.png "屏幕截图.png") #### 任务四、使用Spring框架自带的RestTemplate工具类爬取数据。 ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/152715_41999071_8031809.png "屏幕截图.png") ```java public void fetchCoronavirusData(){ //爬取csv文,指定请求标头 URI uri= UriComponentsBuilder.fromUriString(COVID_DATASOURCE_URL).build(42); //实例化一个RequestEntity对象,通过RestTemplate的exchange方法获取csv文件,封装到body中 RequestEntity requestEntity=RequestEntity.get(uri) .header("User-Agent","Mozilla/5.0") .build(); ResponseEntity exchange=restTemplate.exchange(requestEntity,Resource.class); Resource body=exchange.getBody(); ``` #### 任务五、分析csv文件的数据结构,定义model类。 ```java @Data @AllArgsConstructor//使用后添加一个构造函数 @NoArgsConstructor//使用后创建一个无参构造函数 @Accessors(chain = true)//产生的setter返回的this而不是void public class RegionStats { private String state;//行政区 private String country;//国家 private int latestTotalCases;//确诊总数 private int diffFromPrevDay;//新增病例 } ``` #### 任务六、使用Apache Commons CSV组件解释CSV文件。 >把csv文件的每条记录转换为一个modle类的对象,即上一步中我们定义的model类。 把所有的model类的对象组织为一个集合,如:List 。最终,这个csv文件会转换为一个List对象。 然后我们可以根据实际的业务逻辑,访问这个List即可。 我们可以定义一个Service组件处理csv文件的转换逻辑, 并把最终转换后的List对象赋值给这个Service组件的成员属性,以便应用程序访问这个List对象。 ```java //分析 Excel CSV 文件(标题自动检测)-CSVReccord映射头并获取相应的值 try { Reader in = new InputStreamReader(body.getInputStream()); Iterable records = CSVFormat.RFC4180.withFirstRecordAsHeader().parse(in); for (CSVRecord record : records) { this.allRegionsStats.add(new RegionStats() .setState(record.get("Province/State")) .setCountry(record.get("Country/Region")) .setLatestTotalCases(Integer.valueOf(record.get(record.size() - 1))) .setDiffFromPrevDay(Integer.valueOf(record.get(record.size() - 1)) - Integer.valueOf(record.get(record.size() - 2)))); } } catch (IOException e) { e.printStackTrace(); } //打印日志信息 log.info("Updata CoronavirusData in {}",dataFormat.format(new Date())); } ``` #### 任务七、使用Spring框架自带的计划任务功能定时更新统计数据。 ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/154657_b0b366c5_8031809.png "屏幕截图.png") #### 任务八、8、 要确保应用程序启动时,获取一次统计数据。 >提示: >1、 InitializingBean; >2、 @PostConstruct; >3、 CommandLineRunner; ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/154628_d5035b34_8031809.png "屏幕截图.png") ```java @Component public class InitCoronavirusData implements InitializingBean{ @Autowired private CoronavirusDataService coronavirusDataService; private List allRegionsStats=new ArrayList<>(); @Override public void afterPropertiesSet() throws Exception { log.info("项目启动时会执行,获取一次统计数据!"); coronavirusDataService.getAllRegionsStats(); } } ``` #### 任务九、单元测试。 ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/155946_a120fae2_8031809.png "屏幕截图.png") ```java @SpringBootTest class Experiment3ApplicationTests { @Autowired CoronavirusDataService coronavirusDataService; @Test void testCoronavirusDataService(){ assertTrue(coronavirusDataService.getAllRegionsStats().size()>100); } } ``` #### 任务十、定义Cotroller控制器。 >提示: >1、 使用Java 8的Stream API可以很方便地访问集合类型对象,如:List ; >2、 parallelStream支持并行流,可以大大提升访问性能; >3、 filter方法支持设置过滤条件; >4、 Collectors.toUnmodifiableList()收集为不可变的List集合。 ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/160405_b8b1acfe_8031809.png "屏幕截图.png") ```java package com.example.experiment3.controller; import com.example.experiment3.model.RegionStats; import com.example.experiment3.service.CoronavirusDataService; import com.sun.org.apache.xpath.internal.operations.Mod; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @Controller @RequestMapping("/Data") public class DataController { @Autowired private CoronavirusDataService coronavirusDataService; @GetMapping("/getIndex") public String index( Model model ) { List allRegionsStats = coronavirusDataService.getAllRegionsStats(); model.addAttribute("allRegionsStats",allRegionsStats); return "index"; } @RequestMapping(value = "/findByCountry",method = RequestMethod.POST) public String findByCountryName(String countryname,Model model){ List res = coronavirusDataService.getAllRegionsStats().stream() .filter(rs -> rs.getCountry().contains(countryname)) .collect(Collectors.toList());//抽取集 model.addAttribute("res",res); return "search"; } @RequestMapping(value = "/China",method = RequestMethod.GET) public String China(String cn,Model model){ cn="China"; String finalCn = cn; List res = coronavirusDataService.getAllRegionsStats().stream() .filter(rs -> rs.getCountry().contains(finalCn)) .collect(Collectors.toList());//抽取集合 model.addAttribute("res",res); return "search"; } @RequestMapping(value = "/data",method = RequestMethod.GET) @ResponseBody public List data(String countryname, Model model){ String cn="China"; String finalCn = cn; List COVIDData = coronavirusDataService.getAllRegionsStats().stream() .filter(rs -> rs.getCountry().contains(finalCn)) .collect(Collectors.toList());//抽取集合 List Top10=new ArrayList<>(); // for(int i=0;i<10;i++){ // Top10.add(COVIDData.get(i)); // } return COVIDData; } @RequestMapping(value = "/todata",method = RequestMethod.GET) public String todata(Model model){ return "data"; } } ``` #### 任务十一、定义前端数据展示页面 此次采用**Thymeleaf模板引擎+echarts+layui**来实现前端数据展示页面,利用ajax来实现数据的引入获取图表。 ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/160538_f2c8ad9b_8031809.png "屏幕截图.png") ### 四、实验截图。 >

1、显示全球疫情数据表

![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/161711_1e0d50e8_8031809.png "屏幕截图.png") >-->输入国家名称**Australia**点击搜索,得到该国家各州县疫情数据表 ![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/162104_3f8111dc_8031809.png "屏幕截图.png") >

2、直接显示中国疫情数据表

![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/162326_e644a160_8031809.png "屏幕截图.png") >

3、显示中国疫情图表

![输入图片说明](https://images.gitee.com/uploads/images/2020/1121/162422_62771a11_8031809.png "屏幕截图.png") ### 五、实验总结。

通过此次实验,懂得了如何使用Apache Commons CSV组件解释CSV文件,掌握使用Spring框架自带的RestTemplate工具类爬取网络数据; 学会了利用layui和ajax来接收数据展示前端页面,了解如何使用模板引擎或前端框架展示数据,为以后实战奠定了基础!