This application is supposed to take info on the corona virus from a webpage and output it into a nice table on our own webpage.
All table headers are there but the columns themselves are empty.
Thymeleaf doesn't display data passed to it in model despite data being passed correctly in the controller. I would appreciate any input, thank you.
LocationStats.java (Edited)
package io.javabrains.coronavirustracker.models;
public class LocationStats
{
private String state;
private String country;
private int latestTotalCases;
public String getState() { return this.state; }
public void setState(String state) { this.state = state; }
public String getCountry() { return this.country; }
public void setCountry(String country) { this.country = country; }
public int getLatestTotalCases() { return this.latestTotalCases; }
public void setLatestTotalCases(int latestTotalCases) { this.latestTotalCases = latestTotalCases; }
@Override
public String toString()
{
return "LocationStats{" + "state='" + state + '\'' + ", country='" + country + '\'' + ", latestTotalCases=" + latestTotalCases + '}';
}
}
CoronaVirusDataService.java
package io.javabrains.coronavirustracker.services;
import io.javabrains.coronavirustracker.models.LocationStats;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.StringReader;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
@Service
public class CoronaVirusDataService
{
private static String VIRUS_DATA_URL = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv";
private List<LocationStats> allStats = new ArrayList<>();
public List<LocationStats> getAllStats() { return allStats; }
@PostConstruct
@Scheduled(cron = "* * 1 * * *")
public void fetchVirusData() throws IOException, InterruptedException
{
List<LocationStats> newStats = new ArrayList<>();
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(VIRUS_DATA_URL)).build();
HttpResponse<String> httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(httpResponse.body()); // Prints all data as expected
StringReader csvBodyReader = new StringReader(httpResponse.body());
Iterable<CSVRecord> records = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(csvBodyReader);
for(CSVRecord record : records)
{
LocationStats locationStat = new LocationStats();
locationStat.setCountry(record.get("Country/Region"));
locationStat.setState(record.get("Province/State"));
locationStat.setLatestTotalCases(Integer.parseInt(record.get(record.size() - 1)));
newStats.add(locationStat);
System.out.println(locationStat); // Prints data as expected
}
this.allStats = newStats;
}
}
HomeController.java
package io.javabrains.coronavirustracker.controllers;
import io.javabrains.coronavirustracker.models.LocationStats;
import io.javabrains.coronavirustracker.services.CoronaVirusDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
public class HomeController
{
@Autowired
CoronaVirusDataService coronaVirusDataService;
@GetMapping("/")
public String home(Model model)
{
List<LocationStats> allStats = coronaVirusDataService.getAllStats();
int testNumber = 999; // For test attribute
model.addAttribute("locationStats", allStats); // Actual attribute
model.addAttribute("testInt", testNumber); // Test attribute
return "home";
}
}
home.html (Edited)
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Corona Virus Tracker Application</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<h1 th:text="${testInt}">-1</h1>
<table>
<tr>
<th>State</th>
<th>Country</th>
<th>Total Cases</th>
</tr>
<tr th:each="locationStat : ${locationStats}">
<td th:text="${locationStat.state}"></td>
<td th:text="${locationStat.country}"></td>
<td th:text="${locationStat.latestTotalCases}">0</td>
</tr>
</table>
</body>
</html>
CoronavirusTrackerApplication.java
package io.javabrains.coronavirustracker;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class CoronavirusTrackerApplication
{
public static void main(String[] args)
{
SpringApplication.run(CoronavirusTrackerApplication.class, args);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>io.javabrains</groupId>
<artifactId>coronavirus-tracker</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>coronavirus-tracker</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>14</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>14</source>
<target>14</target>
</configuration>
</plugin>
</plugins>
</build>
</project>