하나씩 차근차근
article thumbnail

앞에서 질문을 등록하고 데이터베이스에 추가하는 기능을 만들었습니다.

하지만 질문을 등록할때 subject 나 content 를 비워두고 등록 버튼을 클릭하면

데이터베이스에는 해당값이 없는채로 등록이 됩니다.

이번에는 값이 비워져있으면 검증을 통해 메세지를 출력하도록 하겠습니다.

 

시작

먼저 pom.xml 파일에 아래와 같이 dependency 를 추가합니다.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

 

QuestionForm 작성

다음으로 question_form 페이지에서 입력값이 제대로 작성되었는지 확인하기 위해서

subject 와 content 를 갖는 QuestionForm 클래스를 작성해서 검증을 하겠습니다.

QuestionForm 클래스는 model 패키지에 작성합니다.

package com.crud.model;

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;
}

위와 같이 subject 의 길이는 최대 200 으로 설정했으며, 

각각의 값이 비어있을 경우 @NotEmpty 를 통해 message 를 표시할 수 있도록 했습니다.

 

QuestionController 수정

앞에서 만든 QuestionController 의 post 방식을 처리해주는 questionCreate 메서드를 다음과 같이 수정합니다.

package com.crud.controller;

import java.util.List;
...
import jakarta.validation.Valid;

@Controller
public class QuestionController {
	
	...
	
	/*
	@PostMapping("question/create")
	public String questionCreate(@RequestParam String subject, @RequestParam String content) {
		questionService.create(subject, content);
		return "redirect:/question/list";
	} */
	
	@PostMapping("question/create")
	public String questionCreate(@Valid QuestionForm questionForm, BindingResult bindingResult) {
		if(bindingResult.hasErrors()) {
			return "question_form";
		}
		questionService.create(questionForm.getSubject(), questionForm.getContent());
		return "redirect:/question/list";
	}
}

questionCreate 메서드는 기존에는 @RequestParam 을 통해 각 입력값을 받았지만,

QuestionForm 객체를 통해 받는것으로 수정했으며, @Valid 를 통해 검증을 하고 있습니다.

@Valid 를 통해 검증한 결과를 bindingResult 를 통해 전달합니다.

 

question_form 수정

다음으로 bindingResult 를 통해 받은 에러메세지를 페이지에 출력하겠습니다.

다음과 같이 에러가 있을 경우 div 태그를 통해 에러메세지를 출력하도록 추가합니다.

<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" th:field="*{subject}" class="form-control">
			</div>
			<div class="mb-3">
				<label for="content" class="form-label">내용</label>
				<textarea th:field="*{content}" class="form-control" rows="10"></textarea>
			</div>
			<input type="submit" value="등록하기" class="btn btn-primary my-2">
		</form>
	</div>
</html>

여기서 중요한점은 th:object 를 통해 폼의 속성들이 QuestionForm 의 속성과 일치하는것을 명시해야합니다.

또한 input 과 textarea 태그의 name 과 id 를 th:field 를 통해 자동으로 생성되도록 수정했습니다.

QuestionController 추가

package com.crud.controller;

import java.util.List;
...
import jakarta.validation.Valid;

@Controller
public class QuestionController {

    ...
	
	@GetMapping("/question/create")
	public String questionCreate(QuestionForm questionForm) {
		return "question_form";
	}
	
}

위와 같이 questionCreate 함수의 매개변수에 QuestionForm 클래스를 추가합니다.

앞으로 Model 이 아닌 QuestionForm 객체를 통해 question_form 에서도 값을 가져올 수 있습니다.

 

결과

위와 같이 입력값을 비우고 등록하기 버튼을 클릭하면 에러메세지가 출력됩니다.

profile

하나씩 차근차근

@jeehwan_lee

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!