반응형
📌 주요 학습 내용
1. 📄 템플릿 레이아웃 구성
기본 템플릿 layout.html
<!-- layout.html -->
<th:block layout:fragment="content"></th:block>
- layout:decorate를 통해 페이지별로 해당 layout을 확장할 수 있음.
2. 🗂 질문 목록 페이지 (question_list.html)
<html layout:decorate="~{layout}">
<center layout:fragment="content">
<h1>자유게시판</h1>
<table class="table">
<thead class="table-dark">
<tr>
<th>번호</th>
<th>제목</th>
<th>작성일자</th>
</tr>
</thead>
<tbody>
<tr th:each="question, loop : ${questionList}">
<td th:text="${loop.count}"></td>
<td><a th:href="@{|/question/detail/${question.id}|}" th:text="${question.subject}"></a></td>
<td th:text="${#temporals.format(question.createDate, 'yyyy-MM-dd')}"></td>
</tr>
</tbody>
</table>
<div class="d-flex justify-content-end">
<a class="btn btn-primary" th:href="@{/question/create}">글작성</a>
</div>
</center>
- 게시글 번호는 loop.count로 출력
- Bootstrap 클래스를 통해 깔끔한 테이블 UI 구현
3. 📝 질문 상세 페이지 (question_detail.html)
<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container my-5">
<div class="card">
<div class="card-body">
<h1 th:text="${question.subject}"></h1>
<div class="badge bg-light text-dark">
작성 일자: <span th:text="${#temporals.format(question.createDate, 'yyyy-MM-dd HH:mm')}"></span>
</div>
<div class="card-text" th:text="${question.content}"></div>
</div>
</div>
<!-- 댓글 리스트 -->
<h5 th:text="|${#lists.size(question.answerList)}개의 댓글이 있습니다.|"></h5>
<div class="card" th:each="answer : ${question.answerList}">
<div class="card-body">
<table>
<tr>
<td><strong>작성자명</strong></td>
<td align="right"><span th:text="${#temporals.format(answer.createDate, 'yyyy-MM-dd HH:mm')}"></span></td>
</tr>
</table>
<div th:text="${answer.content}"></div>
</div>
</div>
<!-- 댓글 등록 -->
<form th:action="@{|/answer/create/${question.id}|}" method="post">
<textarea class="form-control" name="content" rows="3"></textarea>
<input class="btn btn-primary" type="submit" value="답글 등록">
</form>
<a th:href="@{/question/list}">돌아가기</a>
</div>
- 댓글(답글) 리스트 출력 및 등록 폼 추가
- 날짜 포맷 출력: #temporals.format(...) 사용
4. ✅ 질문 등록 기능 구현
📂 QuestionController.java
@GetMapping("/create")
public String questionCreate() {
return "question_form";
}
@PostMapping("/create")
public String questionCreate(@RequestParam("subject") String subject, @RequestParam("content") String content) {
this.questionService.create(subject, content);
return "redirect:/question/list";
}
📂 QuestionService.java
public void create(String subject, String content) {
Question q = new Question();
q.setSubject(subject);
q.setContent(content);
q.setCreateDate(LocalDateTime.now());
this.questionRepository.save(q);
}
- 질문 제목, 내용 입력받아 DB 저장
- 저장 후 질문 목록으로 리다이렉트
💡 포인트 정리
- layout.html을 통한 공통 레이아웃 구성으로 코드 중복 최소화
- layout:decorate와 layout:fragment로 유연한 템플릿 구조 구현
- Bootstrap 테이블과 카드(card)를 사용해 보기 좋은 UI 제공
- @GetMapping과 @PostMapping으로 각각 질문 작성 폼과 등록 처리 분리
- 날짜 포맷은 #temporals.format을 사용해 출력 형식 통일
📌 정리하자면, 54일차에는 질문 등록 기능을 구현하고, 전체 페이지에 Bootstrap UI를 적용하여 사용자 경험을 향상시켰습니다. 게시글 목록, 상세 페이지, 댓글 표시 및 등록까지 완성도 높은 게시판 형태를 갖추어 가는 과정이었습니다.
'국비' 카테고리의 다른 글
[ 57일 22강 ] 수업 정리 - Spring boot (1) | 2025.07.09 |
---|---|
[ 56일차 18~21 ] 수업 정리 - Spring boot (1) | 2025.07.07 |
[ 55일차 ] 복습 (0) | 2025.07.04 |
[ 53일차 8~14 ] 수업 정리 - Spring boot (0) | 2025.07.02 |
[ 52일차 ] 병결로 인한 휴식 (0) | 2025.07.02 |
[ 51일차 1~7 ] 수업 정리 - Spring boot (1) | 2025.06.30 |