# exp-03 **Repository Path**: spverk/exp-03 ## Basic Information - **Project Name**: exp-03 - **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-05-13 - **Last Updated**: 2020-12-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 全球新型冠状病毒实时数据统计应用程序 院(系)名称:网络空间安全学院 专业班级: 17软卓1 学号:201741412129 姓名: 黄思滨 实验题目: 全球新型冠状病毒实时数据统计应用程序 实验日期:2020.5.10 成绩: - - - #### 一、实验目标 1、 掌握使用Spring框架自带的RestTemplate工具类爬取网络数据; 2、 掌握使用Spring框架自带的计划任务功能; 3、 掌握使用Apache Commons CSV组件解释CSV文件; 4、 掌握Java 8的Stream API处理集合类型数据; 5、 了解使用模板引擎或前端框架展示数据。 - - - #### 二、实验环境 - JDK 1.8或更高版本 - Maven 3.6+ - IntelliJ IDEA - commons-csv 1.8+ - - - #### 三、实验任务 1. 通过IntelliJ IDEA的Spring Initializr向导创建Spring Boot项目 创建项目时,添加依赖。
2. 使用Spring框架自带的RestTemplate工具类爬取数据. 1)@Scheduled(cron = "0 0 2 * * *")表示2点定时更新 2)"User-Agent",浏览器开发者工具可知,访问数据源地址需要此参数 ``` java @Scheduled(cron = "0 0 2 * * *") public void fetchCoronaVirusData()throws IOException { RequestEntity requestEntity = RequestEntity.get(URI.create(URL)) .headers(httpHeaders -> httpHeaders.add("User-Agent", "huang")) .build(); ResponseEntity exchange = new RestTemplate().exchange(requestEntity, Resource.class); Resource body = exchange.getBody(); //System.out.println(body); ``` 3.分析csv文件的数据结构,定义model类
4.使用Apache Commons CSV组件解释CSV文件。 1)record.size() - 1指最后一天的值,新增的值为前两天减去前一天的值 ```java final Reader reader = new InputStreamReader(body.getInputStream(), "UTF-8"); final CSVParser parser = new CSVParser(reader, CSVFormat.EXCEL.withHeader()); unitsList.clear(); try { for (final CSVRecord record : parser) { Units units=new Units( record.get("Province/State"), record.get("Country/Region"), Integer.valueOf(record.get(record.size() - 1)), Integer.valueOf(record.get(record.size() - 1))-Integer.valueOf(record.get(record.size() - 2)) ); unitsList.add(units); } //System.out.println(unitsList); } catch (Exception e) { System.out.println(e.getMessage()); }finally { parser.close(); reader.close(); } ``` 5.Spring Boot在初始化计划任务线程池的时候,设置线程池大小是25
6.要确保应用程序启动时,获取一次统计数据,在这里我们使用InitializingBean ```java public void afterPropertiesSet()throws IOException{ fetchCoronaVirusData(); } ``` 7.单元测试及其运行结果。 ```java @Test void init() { System.out.println(InitServices.unitsList); } ```
```java @Test void search(){ ListunitsList=searchServices.search("China"); Assert.isTrue(unitsList.size()>0,"搜索失败"); } ```
```java @Test void search(){ ListunitsList=searchServices.search("Cxhina"); Assert.isTrue(unitsList.size()>0,"搜索失败"); } ```
```java @Test void homeing() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/")) .andDo(print()); } ```
```java @Test void searching() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/search?key=China")) .andDo(print()); } ```
8.定义Cotroller控制器 1)total:总数 plus:增加人数 unitList:全部国家数据细明 keyList:关键国家数据细明 ```java //首页控制器 @RequestMapping("/") public String home(Model model){ int total=0; int plus=0; for(Units units: InitServices.unitsList){ total+=units.getLatestTotalCases(); plus+=units.getDiffFromPrevDay(); } model.addAttribute("total",total); model.addAttribute("plus",plus); model.addAttribute("unitsList",InitServices.unitsList); return "index"; } //查询控制器 @RequestMapping("/search") public String search(Model model,String key){ int total=0; int plus=0; SearchServices searchServices=new SearchServices(); for(Units units: searchServices.search(key)){ total+=units.getLatestTotalCases(); plus+=units.getDiffFromPrevDay(); } model.addAttribute("total",total); model.addAttribute("plus",plus); model.addAttribute("keyList",searchServices.search(key)); return "search"; } ``` 9.定义前端数据展示页面 1)首页展示
2)查询页面展示 (查询China)