해당 게시글은 점프 투 스프링부트 교재를 통한 개인 학습 용도이며 기초 세팅은 생략하였습니다.
자바 8, 스프링부트 2.7.7버전입니다.
질문 상세 링크 추가하기
question_list.html을 다음과 같이 수정하자
<table>
<thead>
<tr>
<th>제목</th>
<th>작성일시</th>
</tr>
</thead>
<tbody>
<tr th:each="question : ${questionList}">
<td>
<a th:href="@{|question/detail/${question.id}" th:text="${question.subject}"></a>
</td>
<td th:text="${question.createDate}"></td>
</tr>
</tbody>
</table>
타임리프에서 링크의 주소는 th:href속성을 사용한다. URL 주소를 나타낼 때 반드시 @{URL}형식을 지켜야 한다.
문자열과 자바 객체의 값을 더할 때는 반드시 | | 기호로 좌우를 감싸주어야 한다.
타임리프는 문자열을 연결할 때 | 문자를 사용한다
질문 상세 구현하기
Question 데이터를 조회하기 위해 QuestionService를 수정하자
(... 생략 ...)
import java.util.Optional;
import com.example.board.DataNotFoundException;
(... 생략 ...)
public class QuestionService {
(... 생략 ...)
public Question getQuestion(Integer id) {
Optional<Question> question = this.questionRepository.findById(id);
if(question.isPresent()) {
return question.get();
}
else {
throw new DataNotFoundException("질문이 없음");
}
}
}
id 값으로 Question 데이터를 조회하는 getQuestion 메서드를 추가했다.
리포지터리로 얻은 Question 객체는 Optional 객체이기 때문에 isPresent 메서드로 해당 데이터가 존재하는지 검사하는 로직이 필요하다. 만약 id값에 해당하는 Question 데이터가 없을 경우 DataNotFoundException을 발생시키도록 했다.
DataNotFoundException 클래스를 생성하자
package com.example.board;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "entity not fonud")
public class DataNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public DataNotFoundException(String message) {
super(message);
}
}
DataNotFoundException은 RuntimeException을 상속하여 만들었다.
만약 DataNotFoundException이 발생하면 @ResponseStatus 애너테이션에 의해 404 오류(HttpStatus.NOT_FOUND)가 나타날 것이다.
질문 상세 페이지에 대한 URL 매핑을 QuestionController에 추가하자
또한 QuestionService의 getQuestion 메서드를 호출하여 Question 객체를 템플릿에 전달할 수 있도록 수정하자
(... 생략 ...)
import org.springframework.web.bind.annotation.PathVariable;
(... 생략 ...)
public class QuestionController {
(... 생략 ...)
@GetMapping(value = "/question/detail/{id}")
public String detail(Model model, @PathVariable("id") Integer id) {
Question question = this.questionService.getQuestion(id);
model.addAttribute("question", question);
return "question/question_detail";
}
}
이제 질문 상세 템플릿을 만들자
경로 : /practice/src/main/resources/templates/question/question_detail.html
<h1 th:text="${question.subject}"></h1>
<div th:text="${question.content}"></div>
데이터가 존재할 경우 화면에 잘 출력이 될 것이고
존재하지 않는 데이터를 조회 할 경우 404 Not found 오류가 발생할 것이다
URL 프리픽스(prefix)
QuestionController의 URL 매핑을 살펴보면 모두 /question으로 시작한다는 것을 알 수 있다.
이런 경우 클래스명 위에 @RequestMapping("/question") 애너테이션을 추가하고 메서드 위에서는 /question을 생략할 수 있다
(... 생략 ...)
import org.springframework.web.bind.annotation.RequestMapping;
(... 생략 ...)
@RequestMapping("/question")
@RequiredArgsConstructor
@Controller
public class QuestionController {
private final QuestionService questionService;
@GetMapping("/list")
public String list(Model model) {
(... 생략 ...)
}
@GetMapping(value = "/detail/{id}")
public String detail(Model model, @PathVariable("id") Integer id) {
(... 생략 ...)
}
}
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!