Day 43 - Spring Boot pt.3

haxxru log;·2026년 4월 30일
post-thumbnail

이 글은 2026년 04월 30일 작성된 글입니다.

오늘은 답변 등록 기능, Bootstrap 화면 구성,
질문 등록 기능과 validation 처리까지 정리했다.


1. 답변 등록 폼 추가

질문 상세 페이지에서 답변을 입력할 수 있도록 폼을 추가했다.

<form action="/answer/create/" method="post">
    <textarea name="content" id="content" rows="15"></textarea>
    <input type="submit" value="답변등록">
</form>

처음에는 답변 내용만 서버로 보내는 구조로 시작했다.

  • textarea로 답변 내용 입력
  • POST 방식으로 답변 데이터 전송

2. 질문과 답변 연결

답변은 특정 질문에 달려야 하므로,
질문 id를 URL에 포함해서 전달하도록 수정했다.

<form th:action="@{|/answer/create/${question.id}|}" method="POST">
    <textarea name="content" cols="30" rows="10"></textarea>
    <input type="submit" value="답변등록">
</form>

이렇게 하면 서버는 어떤 질문에 대한 답변인지 알 수 있다.

  • 질문 id를 path variable로 전달
  • 답변과 질문을 연결

3. 답변 목록 출력

질문 상세 페이지에서 해당 질문에 달린 답변 목록을 출력했다.

<h5 th:text="|${#lists.size(question.answerList)}개의 답변이 있습니다.|"></h5>

<ul>
    <li th:each="answer : ${question.answerList}" th:text="${answer.content}"></li>
</ul>

question.answerList를 사용하면
질문에 연결된 답변들을 화면에 출력할 수 있다.

  • 답변 개수 출력
  • 답변 목록 반복 출력

4. Bootstrap으로 화면 꾸미기

기본 HTML 화면에 Bootstrap을 적용해서
화면을 더 보기 좋게 구성했다.

<input type="submit" value="답변등록" class="btn btn-primary">

Bootstrap을 사용하면 직접 CSS를 많이 작성하지 않아도
버튼, 폼, 여백 등을 빠르게 정리할 수 있다.

  • 버튼 스타일 적용
  • 폼 디자인 개선
  • 화면 가독성 향상

5. 표준 HTML 구조 적용

페이지 구조를 더 명확하게 만들기 위해
표준 HTML 구조로 변경했다.

<html>
<head>
    <title>질문 게시판</title>
</head>
<body>
    <main>
        <!-- content -->
    </main>
</body>
</html>

기본 구조를 잡아두면
이후 공통 레이아웃을 적용하기도 쉬워진다.


6. 질문 등록 폼 추가

새 질문을 작성할 수 있도록 질문 등록 폼을 만들었다.

<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container">
    <h5 class="my-3 border-bottom pb-2">질문등록</h5>
    <form th:action="@{/question/create}" method="post">
        <div class="mb-3">
            <label for="subject" class="form-label">제목</label>
            <input type="text" name="subject" id="subject" class="form-control">
        </div>
        <div class="mb-3">
            <label for="content" class="form-label">내용</label>
            <textarea name="content" id="content" class="form-control" rows="10"></textarea>
        </div>
        <input type="submit" value="저장하기" class="btn btn-primary my-2">
    </form>
</div>
</html>

질문 등록 폼에서는 제목과 내용을 입력받는다.

  • 제목 입력
  • 내용 입력
  • POST 방식으로 서버 전송

7. 질문 등록 구현

폼에서 전달된 제목과 내용을 받아
질문 데이터를 저장하도록 구현했다.

흐름은 다음과 같다.

  1. 사용자가 질문 등록 폼 작성
  2. submit
  3. Controller에서 요청 처리
  4. Service를 통해 Question 저장
  5. 저장 후 목록 또는 상세 페이지로 이동

8. Validation 의존성 추가

질문 등록 시 빈 값이 들어오지 않도록 validation을 적용했다.

implementation("org.springframework.boot:spring-boot-starter-validation")

validation을 적용하면
폼 데이터가 서버에 들어온 뒤 조건에 맞는지 검사할 수 있다.

  • 제목 필수 입력
  • 내용 필수 입력
  • 잘못된 요청 방지

9. 질문 등록 폼 에러 처리

폼에서 에러가 발생했을 때
사용자에게 에러 메시지를 보여주도록 처리했다.

<form th:action="@{/question/create}" th:object="${questionForm}" method="post">
    <div class="alert alert-danger" role="alert" th:if="${#fields.hasAnyErrors()}">
        <div th:each="err : ${#fields.allErrors()}" th:text="${err}"></div>
    </div>

    <input type="text" th:field="*{subject}" class="form-control">
    <textarea th:field="*{content}" class="form-control" rows="10"></textarea>

    <input type="submit" value="저장하기" class="btn btn-primary my-2">
</form>

th:objectth:field를 사용하면
폼 객체와 입력 필드를 자연스럽게 연결할 수 있다.

  • 에러 메시지 출력
  • 입력 필드와 Form 객체 연결
  • 사용자 입력 검증

10. 답변 등록 폼 validation 적용

답변 등록 폼에도 validation을 적용했다.

<form th:action="@{|/answer/create/${question.id}|}" th:object="${answerForm}" method="post" class="my-3">
    <div class="alert alert-danger" role="alert" th:if="${#fields.hasAnyErrors()}">
        <div th:each="err : ${#fields.allErrors()}" th:text="${err}"></div>
    </div>

    <textarea th:field="*{content}" rows="10" class="form-control"></textarea>
    <input type="submit" value="답변등록" class="btn btn-primary my-2">
</form>

질문 등록과 답변 등록 모두
폼 객체를 기준으로 유효성 검사를 처리하는 구조가 되었다.


11. 공통 템플릿 적용

여러 화면에서 반복되는 레이아웃을 공통 템플릿으로 분리했다.

<html layout:decorate="~{layout}">
<div layout:fragment="content">
    <!-- 페이지별 내용 -->
</div>
</html>

공통 레이아웃을 사용하면
전체 페이지 구조를 일관성 있게 유지할 수 있다.

  • 중복 코드 감소
  • 화면 구조 통일
  • 유지보수 편의성 증가

✅ 정리

  • 답변 등록 기능은 질문 id와 함께 요청을 보내야 특정 질문에 연결할 수 있다.
  • Thymeleaf의 th:action, th:object, th:field를 사용하면 폼 처리가 훨씬 깔끔해진다.
  • Bootstrap을 적용하면 화면을 빠르게 정리하고 가독성을 높일 수 있다.
  • Validation을 적용하면 잘못된 입력을 서버에서 안정적으로 막을 수 있다.
  • 공통 템플릿을 사용하면 여러 페이지의 레이아웃을 일관되게 관리할 수 있다.

0개의 댓글