하나씩 차근차근
article thumbnail

앞에서 만든 질문 등록 기능과 비슷하게 답변 등록 기능을 만들겠습니다.

 

AnswerForm 작성

package com.crud.model;

import jakarta.validation.constraints.NotEmpty;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class AnswerForm {

	@NotEmpty(message = "내용을 입력해주세요.")
	private String content;
}

답변은 content 만 있으므로 AnswerForm 은 content 하나만 속성으로 갖습니다.

 

AnswerController 수정

다음으로 AnswerController 를 AnswerForm 을 통해 검증을 할 수 있도록 수정합니다.

package com.crud.controller;
...
import jakarta.validation.Valid;

@Controller
public class AnswerController {
	
	...

	/*
	@PostMapping("/answer/create/{id}")
	public String createAnswer(Model model, @PathVariable("id") Integer id, @RequestParam String content) {
		
		Question question = questionService.getQuestion(id);
		answerService.create(question, content);
		
		return String.format("redirect:/question/detail/%s", id);
	} */
	
	@PostMapping("/answer/create/{id}")
	public String createAnswer(Model model, @PathVariable("id") Integer id, @Valid AnswerForm answerForm, BindingResult bindingResult) {
		
		Question question = questionService.getQuestion(id);
		
		if(bindingResult.hasErrors()) {
			model.addAttribute("question", question);
			return "question_detail";
		}
		
		answerService.create(question, answerForm.getContent());
		
		return String.format("redirect:/question/detail/%s", id);
	}
}

기존의 createAnswer 메서드는 @RequestParam 을 통해 content 값을 받았는데

앞으로 AnswerForm 을 통해 값을 받고 검증을 할 수 있도록 수정했습니다.

만약 에러가 있을 경우 question_detail.html 다시 출력하고 model 을 통해 해당 question 을 다시 전달합니다.

 

question_detail 추가

다음으로 question_detail 파일에서 에러메세지를 출력하도록 하겠습니다.

<html layout:decorate="~{layout}">
	<div layout:fragment="content" class="container my-3">
		...	
		<form class="my-3" th:action="@{|/answer/create/${question.id}|}" th:object="${answerForm}" method="post">
			<div class="alert alert-danger" role="alert" th:if="${#fields.hasAnyErrors()}">
				<div th:each="err : ${#fields.allErrors()}" th:text="${err}" />
			</div>
			<textarea class="form-control" th:field="*{content}" rows="15"></textarea>
			<input class="btn btn-primary my-2" type="submit" value="답변등록">
		</form>
	</div>
</html>

앞에서 작성한 question_form 파일과 동일하게 question_detail 의 form 태그도 answerForm 을 통해 검증할 수 있도록

에러메세지를 출력하는 div 태그를 추가하고 textarea 의 name을 삭제하고 th:field 로 수정합니다.

 

QuestionController 추가

마지막으로 QuestionController 의 detail 메서드에서 AnswerForm 을 사용하는 question_detail 파일을 return 하기 때문에

매개변수에 AnswerForm 을 추가해야 합니다.

package com.crud.controller;

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

@Controller
public class QuestionController {
	
	...
	
	@GetMapping("/question/detail/{id}")
	public String detail(Model model, @PathVariable("id") Integer id, AnswerForm answerForm) {
		Question question = questionService.getQuestion(id);
		model.addAttribute("question", question);
		
		return "question_detail";
	}
	...
}

 

결과

답변을 입력하고 답변등록을 클릭하면 아래와 같이 답변이 등록됩니다.

만약 답변 입력란에 아무 입력을 하지 않은채로 답변등록 버튼을 클릭하면 에러메세지가 출력됩니다.

profile

하나씩 차근차근

@jeehwan_lee

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