//question_list.html
... 생략
</table>
<a th:href="@{/question/create}" class="btn btn-primary">질문 등록하기</a> //추가
//QuestionController.java
@GetMapping("/create")
public String questionCreate() {
return "question_form";
}
@PostMapping("/create")//form.html에서 post방식으로 전달했기 때문에 PostMapping 방식 사용
public String questionCreate(@RequestParam(value="subject") String subject,
@RequestParam(value="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);
} //추
//question_form.html
<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container">
<h5 class="my-3 border-bottom pb-2">질문등록</h5>
<form th:action="@{/question/create}" th:object="${questionForm}" 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>
사용자가 작성한 값을 서버로 보낼 때 가장 쉬운 방법 → form 태그 이용
새로운 질문이 성공적으로 저장된 것을 확인할 수 있다.
폼 클래스를 사용해 사용자로부터 입력받은 값을 검증하기 위해 Spring Boot Validation 라이브러리가 필요하다.
//build.gradle
implementation 'org.springframework.boot:spring-boot-starter-validation'
Spring Boot Validation 라이브러리를 설치하면 다음과 같은 애너테이션을 사용하여 사용자가 입력한 값을 검증할 수 있다.
항목 | 설명 |
---|---|
@Size | 문자 길이를 제한한다. |
@NotNull | Null을 허용하지 않는다. |
@NotEmpty | Null 또는 빈 문자열(””)을 허용하지 않는다. |
@Past | 과거 날짜만 입력할 수 있다. |
@Future | 미래 날짜만 입력할 수 있다. |
@FutureOrPresent | 미래 또는 오늘 날짜만 입력할 수 있다. |
@Max | 최댓값 이하의 값만 입력할 수 있도록 제한한다. |
@Min | 최솟값 이상의 값만 입력할 수 있도록 제한한다. |
@Pattern | 입력값을 정규식 패턴으로 검증한다. |
입력값을 검증하는데 필요한 폼 클래스 만들기
//QuestionForm.java
package com.mysite.sbb.question;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class QuestionForm {
@NotEmpty(message = "제목은 필수항목입니다.")
@Size(max = 200)
private String subject;
@NotEmpty(message = "내용은 필수항목입니다.")
private String content;
}
//QuestionController.java
@GetMapping("/create")
public String questionCreate(QuestionForm questionForm) {
//th:object에 의해 QuestionForm 객체가 필요하게 됨
return "question_form";
}
@PostMapping("/create")
public String questionCreate(@Valid QuestionForm questionForm,
BindingResult bindingResult) {
if(bindingResult.hasErrors()) {
return "question_form";
}
this.questionService.create(questionForm.getSubject(),
questionForm.getContent()); //질문 저장
return "redirect:/question/list"; //질문 저장 후 질문 목록으로 이동
} //수정
//question_form.html
<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container">
<h5 class="my-3 border-bottom pb-2">질문등록</h5>
<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 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>