(7) 답변 등록하기
답변 페이지 만들기
시작하기 전에
개요 : 질문과 답변을 할 수 있는 게시판 서비스를 스프링부트를 통해 만들어 본다.
학습사이트 : https://wikidocs.net/book/7601
예제 코드 : https://github.com/pahkey/sbb
질문 상세 화면에서 답변을 입력하기 위한 버튼을 생성하고, 이 버튼을 누르면 답변이 저장되도록 구현해보자
답변 등록 버튼 만들기
- 질문 상세 테이블에 답변 등록 버튼 추가
-
question_detail.html 수정
<!-- 경로 : sbb/src/main/resources/templates/question_detail.html --> <h1 th:text="${question.subject}"></h1> <div th:text="${question.content}"></div> <!-- 답변 등록 from태그 : post방식 --> <form th:action="@{|/answer/create/${question.id}|}" method="post"> <textarea name="content" id="content" rows="15"></textarea> <input type="submit" value="답변등록"> </form>
- 답변등록 버튼을 누르면 /answer/create/<질문id> url 호출질문id>
- 아직 만들지 않았으므로 오류
답변 컨트롤러 만들기
-
AnswerController.java 만들기
// 경로 : sbb/src/main/java/com/mysite/sbb/answer/AnswerController.java package com.mysite.sbb.answer; import com.mysite.sbb.question.Question; import com.mysite.sbb.question.QuestionService; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @RequestMapping("/answer") // URL 프리픽스 : 메서드 단위에서 (/answer) 생략 가능 @RequiredArgsConstructor @Controller public class AnswerController { private final QuestionService questionService; // post요청만 받아들일 경우에 사용하는 에너테이션 @PostMapping("/create/{id}") // (value=) 생략가능 public String createAnswer(Model model, @PathVariable("id") Integer id, @RequestParam String content) { Question question = this.questionService.getQuestion(id); // TODO: 답변을 저장하는 코드 예정 return String.format("redirect:/question/detail/%s", id); } }
- @RequestParam : 답변으로 입력한 내용을 넘겨주기 위해 추가
- 템플릿의 form태그에 textarea의 name 속성명이 content이기 때문에 여기서도 변수명은 content로 사용해주어야 함
- TODO: 아직 안한일을 적어두는 용도로, 지우고 그냥 주석으로 달아도 되긴 한다
답변 저장하기
답변을 저장하려면 엔티티 객체를 핸들링 해주는 서비스가 필요
-
AnswerService.java 만들기
// 경로 : sbb/src/main/java/com/mysite/sbb/answer/AnswerService.java package com.mysite.sbb.answer; import com.mysite.sbb.question.Question; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.time.LocalDateTime; @RequiredArgsConstructor @Service public class AnswerService { private final AnswerRepository answerRepository; // 답변 생성 메서드 // form 태그로부터 받은 question과 content를 사용하여 객체를 생성하여 저장 public void create(Question question, String content) { Answer answer = new Answer(); answer.setContent(content); answer.setCreateDate(LocalDateTime.now()); answer.setQuestion(question); this.answerRepository.save(answer); } }
- AnswerController.java 수정
- 서비스에서 작성한 create 메서드 사용
// 경로 : sbb/src/main/java/com/mysite/sbb/answer/AnswerController.java package com.mysite.sbb.answer; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import com.mysite.sbb.question.Question; import com.mysite.sbb.question.QuestionService; import lombok.RequiredArgsConstructor; @RequestMapping("/answer") // URL 프리픽스 @RequiredArgsConstructor @Controller public class AnswerController { private final QuestionService questionService; // 변수 지정 private final AnswerService answerService; // post요청만 받아들일 경우에 사용하는 에너테이션 @PostMapping("/create/{id}") // (value=) 생략가능 public String createAnswer(Model model, @PathVariable("id") Integer id, @RequestParam String content) { Question question = this.questionService.getQuestion(id); // 답변저장 this.answerService.create(question, content); return String.format("redirect:/question/detail/%s", id); } }
- 이전에 TODO자리에 create 메서드를 호출하는 코드 작성
질문 상세 페이지에 답변 표시하기
답변을 저장하는 메서드는 잘 동작하지만, 템플릿에 표시하는 기능은 아직 추가하지 않았으므로 detail 템플릿 수정 필요
-
question_detail.html 수정
<!-- 경로 : sbb/src/main/resources/templates/question_detail.html --> <h1 th:text="${question.subject}"></h1> <div th:text="${question.content}"></div> <!-- 답변을 확인할 수 있는 영역 추가 --> <h5 th:text="|${#lists.size(question.answerList)}개의 답변이 있습니다.|"></h5> <div> <ul> <li th:each="answer : ${question.answerList}" th:text="${answer.content}"></li> </ul> </div> <!-- 답변 등록 from태그 : post방식 --> <form th:action="@{|/answer/create/${question.id}|}" method="post"> <textarea name="content" id="content" rows="15"></textarea> <input type="submit" value="답변등록"> </form>
- ${#lists.size(question.answerList) : 질문에 달린 답변의 갯수를 의미
- 답변이 여러개일수도 있으므로 목록태그인 li 엘리먼트로 작성
저장된 답변 확인
답변이 웹에 잘 표시된다.
Leave a comment