국비

[ 54일차 15~17 ] 수업 정리 - Spring boot

코딩하는냥이 2025. 7. 3. 15:50
반응형

📌 주요 학습 내용

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를 적용하여 사용자 경험을 향상시켰습니다. 게시글 목록, 상세 페이지, 댓글 표시 및 등록까지 완성도 높은 게시판 형태를 갖추어 가는 과정이었습니다.