2024. 6. 17. 17:17ㆍSpring-Project
이전글 : https://codepracticeroom.tistory.com/202
이번에는 받은 데이터를 좀 더 가공하고 웹에 띄워볼 것이다.
먼저 domain에 WeatherData에 순서, 날짜, 시간 데이터를 추가해 준다.
순서는 PK로 사용한다.
이전글에서 온도와 시간을 String로 하였는데 여기서는 double 형태로 변환한다.
WeatherData
@Getter
@Setter
public class WeatherData {
@Id
private long sequence; //Pk
private LocalDate date; //날짜
private LocalTime time; //시간
private double temperature; //온도
private double humidity; //시간
}
Service에 최근 DB데이터 중 하나를 가져오는 코드를 작성한다.
WeatherService
@Service
@RequiredArgsConstructor
public class WeatherService {
private final WeatherRepository weatherRepository;
private final MongoTemplate template; //MongoDBTemplate 의존성 주입
@Transactional
public void save(WeatherData weatherData){
weatherRepository.save(weatherData);
}
public long count(){ // DB 데이터의 개수
return weatherRepository.count();
}
public WeatherData findLatestData() {
Query query = new Query();
query.with(Sort.by(Sort.Direction.DESC, "date","time")).limit(1); // 날짜, 시간을 내림차순으로 정렬, 하나 추출
return template.findOne(query, WeatherData.class);
}
}
이제 Controller의 GetMapping를 만들어 줘야 한다.
DataController
@Slf4j
@Controller
@RequiredArgsConstructor
public class DataController {
private final WeatherService weatherService;
private static long count;
@GetMapping("/")
public String getHome(Model model){
model.addAttribute("weatherData", weatherService.findLatestData());
return "home";
}
@ResponseBody
@PostMapping("/home")
public String postData(@RequestBody WeatherData weatherData){
if(count != 0){
weatherData.setSequence(++count);
} else {
count = weatherService.count()+1;
weatherData.setSequence(weatherService.count()+1);
}
weatherData.setDate(LocalDate.now()); // 현재 날짜
weatherData.setTime(LocalTime.now()); // 현재 시간
weatherData.setHumidity(Math.round(weatherData.getHumidity()*100)/100.0); //소수점 3번째에서 반올림
weatherData.setTemperature(Math.round(weatherData.getTemperature()*100)/100.0); //소수점 3번째에서 반올림
weatherService.save(weatherData);
log.info("temp={} hum={}", weatherData.getTemperature(), weatherData.getHumidity());
return "";
}
}
Service에서 만들었던 findLastestData를 가져와서 Model에 넣고 return을 templates의 "home"으로 한다.
html에서 CSS를 사용하기 때문에 먼저 CSS를 다운로드하여야 한다.
Bootstrap
강력하고 확장 가능하며 기능이 풍부한 프론트엔드 툴킷. Sass로 빌드 및 커스터마이징하고, 사전 빌드된 그리드 시스템 및 구성 요소를 활용하고, 강력한 JavaScript 플러그인으로 프로젝트에 생기
getbootstrap.kr
다운로드 - 컴파일된 CSS와 JS를 다운로드한다.
다운로드한 파일을 압축 해제한다.
필요한 파일은 bootstrap.min.css이다.
스프링의 resources - static에 이름은 "css"로 디렉터리를 하나 만든다.
만든 곳에 bootstrap.min.css를 넣는다.
그다음 resources - templates에 home.html를 만들고 작성한다.
Home.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<link href="../css/bootstrap.min.css"
th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<style>
body {
padding-top: 20px;
}
.container {
background-color: #f8f9fa;
border-radius: 5px;
padding: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, .1);
}
#txt {
margin-bottom: 20px;
font-size: 20px;
font-weight: bold;
}
.form-inline > div {
margin-bottom: 10px;
font-size: 16px;
}
.btn-primary {
text-decoration: none;
color: white;
background-color: #007bff;
padding: 10px 15px;
border-radius: 5px;
transition: background-color 0.2s;
}
.btn-primary:hover {
background-color: #0056b3;
}
.form-container {
background-color: #ffffff;
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
margin-top: 20px;
}
.form-container h3 {
color: #007bff;
margin-bottom: 20px;
text-align: center;
}
.form-row {
display: flex;
margin-bottom: 10px;
}
.form-label {
flex-basis: 20%;
font-weight: bold;
}
.form-value {
flex-grow: 1;
}
</style>
<script>
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
var ampm = h >= 12 ? '오후' : '오전';
h = h % 12;
h = h ? h : 12;
m = checkTime(m);
s = checkTime(s);
document.getElementById('txt').innerHTML =
"현재시간 : " + ampm + " " + h + ":" + m + ":" + s + " ";
var t = setTimeout(startTime, 500);
}
function checkTime(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
</script>
</head>
<body onload="startTime()">
<div id="txt"></div>
<div class="container">
<div class="py-5 text-center">
<h2>측정</h2>
</div>
<div class="row">
<div class="col">
<button class="btn btn-primary float-end" th:onclick="|location.href='@{/list}'|" type="button">모두보기</button>
</div>
</div>
<div class="container">
<div class="form-container">
<form th:object="${weatherData}" method="get">
<div class="form-row">
<span class="form-label">날짜 :</span>
<span class="form-value" th:text="${weatherData.date}"></span>
</div>
<div class="form-row">
<span class="form-label">시간 :</span>
<span class="form-value" th:text="${#temporals.format(weatherData.time, 'HH:mm:ss')}"></span>
</div>
<div class="form-row">
<span class="form-label">온도 :</span>
<span class="form-value" th:text="${weatherData.temperature} + ' ℃'"></span>
</div>
<div class="form-row">
<span class="form-label">습도 :</span>
<span class="form-value" th:text="${weatherData.humidity} + ' %'"></span>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
스프링 실행 후 localhost에 접속하면 화이트라벨 에러가 뜰 수도 있다.
예전에 MongoDB에 저장하였던 데이터 타입이 맞지 않아서 뜨는 오류이다.
MongoDB의 데이터를 삭제한 후 다시 아두이노를 연결하여 데이터를 쌓고
localhost에 접속하며 정상적으로 웹 페이지가 뜬다.
'Spring-Project' 카테고리의 다른 글
Arduino와 SpringBoot를 사용한 온습도 측정 사이트(완) - SpringBoot편 (0) | 2024.06.19 |
---|---|
Arduino와 SpringBoot를 사용한 온습도 측정 사이트(7) - SpringBoot편 (0) | 2024.06.18 |
Arduino와 SpringBoot를 사용한 온습도 측정 사이트(5) - SpringBoot편 (0) | 2024.06.17 |
Arduino와 SpringBoot를 사용한 온습도 측정 사이트(4) - SpringBoot편 (0) | 2024.06.14 |
Arduino와 SpringBoot를 사용한 온습도 측정 사이트(3) - Arduino편 (0) | 2024.06.14 |