3편 중후반부에 Controller 부분에서 오류가 발생하면 오류를 던졌다.
if (book.getName() == null || book.getIsbn() == null) {
// 유효성 검사 실패 시 적절한 응답 반환
log.error("북 이름, isbn이 필요합니다.");
throw new Exception("북 이름, isbn 값이 필요합니다");
//return ResponseEntity.badRequest().body("Book name and ISBN are required.");
}
try {
log.info("책 정보를 db에 저장합니다.");
//책 정보를 db에 저장
bookService.saveBook(book);
// 적절한 응답 반환
return "redirect:/home";
} catch (DuplicateIsbnException e) {
// 중복된 ISBN이 발생한 경우 적절한 응답 반환
log.error("중복된 ISBN이 발생했습니다: {}", e.getMessage());
throw new DuplicateIsbnException("중복된 ISBN입니다.", e);
//return ResponseEntity.badRequest().body("중복된 ISBN입니다.");
} catch (Exception e) {
// 저장 중에 예외가 발생한 경우 적절한 응답 반환
log.error("저장 중 예외가 발생하였습니다.");
throw new Exception("장바구니에 이미 해당 책이 있습니다. 추가할 수 없습니다.", e);
//return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("장바구니에 이미 해당 책이 있습니다. 추가할 수 없습니다");
}
}else {
log.info("bookList가 제대로 반환되지 않았습니다");
//return ResponseEntity.badRequest().body("책 정보를 찾을 수 없습니다.");
throw new Exception("책 정보를 찾을 수 없습니다.");
}
}
먼저 그래서 이 오류를 처리할 수 있는 error.html을 생성한다.
<!DOCTYPE html>
<html lang="en" xdata-bs-theme="auto" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Error Page</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="styles.css">
<link href="../assets/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="/css/bootstrap.min.css" integrity="sha384ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link href="/css/jumbotron-narrow.css" rel="stylesheet">
<style>
.btn-bd-primary {
--bd-violet-bg: #712cf9;
--bd-violet-rgb: 112.520718, 44.062154, 249.437846;
--bs-btn-font-weight: 600;
--bs-btn-color: var(--bs-white);
--bs-btn-bg: var(--bd-violet-bg);
--bs-btn-border-color: var(--bd-violet-bg);
--bs-btn-hover-color: var(--bs-white);
--bs-btn-hover-bg: #6528e0;
--bs-btn-hover-border-color: #6528e0;
--bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
--bs-btn-active-color: var(--bs-btn-hover-color);
--bs-btn-active-bg: #5a23c8;
--bs-btn-active-border-color: #5a23c8;
}
</style>
</head>
<body>
<div class="d-flex align-items-center justify-content-center vh-100">
<div class="text-center">
<h1 class="display-1 fw-bold">Bad Request!</h1>
<p class="fs-3"> <span class="text-danger">Opps!</span></p>
<p class="lead">
<p th:text="${errorMessage}" style="font-weight: bold; font-size: 24px;"></p>
<p style="font-size: 22px;">위에 표시된 오류를 다시 한 번 확인해주세요.</p>
<a href="/login" class="btn btn-bd-primary">Go Home</a>
</div>
</div>
</body>
</html>
이렇게 생성해주고 th:text="${errorMessage}" <- 여 부분에 모든 컨트롤러에서 발생하는 예외들을 여기에서 처리하도록 한다. 이를 위해 @ControllerAdvice를 사용한다!
Handler 파일 하나를 만들어 GlobalExceptionHandler.class 생성
package Book_Toy_Project.BOOK.Handler;
import Book_Toy_Project.BOOK.Exception.DuplicateIsbnException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(DuplicateIsbnException.class)
private ModelAndView handleDuplicateIsbnException(DuplicateIsbnException e) {
ModelAndView modelAndView = new ModelAndView("error/error");
modelAndView.addObject("errorMessage", e.getMessage());
return modelAndView;
}
...
그리고 @ExceptionHandler(DuplicateIsbnException.class) 이런식으로 작성한 후, 해당 "DuplicateIsbnException" 오류가 터졌을 때 이 메서드가 무조건 실행되도록 한다.
실행 되면 (DuDuplicateIsbnException) -> e.getMessage()를 error/error.html로 보내준다!
오류 나오는 예)
이런식으로 보인다면 성공!