๋ฐ์ํ
1. ๋ชฉํ
- ์ปจํธ๋กค๋ฌ์์ ์์ธ ๋ฐ์ ์, ์ฌ์ฉ์๊ฐ ์๋ฌ ๋ฉ์์ง๋ฅผ ํ์ธํ ํ ์ผ์ ์๊ฐ ๋ค ์๋์ผ๋ก / ๋ฉ์ธ ํ์ด์ง๋ก ์ด๋ํ๋๋ก ๊ตฌ์ฑ
- ์ปค์คํ ์์ธ CustomException๊ณผ ์ผ๋ฐ ์์ธ ๋ชจ๋ ์ฒ๋ฆฌ
๋ทฐ๋จ ํ ํ๋ฆฟ์ ํ์๋ฆฌํ ์ฌ์ฉํจ.
2. ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ
src/
โโโ main/
โโโ java/
โโโ com.example.demo/
โโโ controller/
โ โโโ TestController.java
โโโ global/
โโโ exception/
โโโ CustomException.java
โโโ GlobalExceptionHandler.java
โโโ resources/
โโโ templates/
โ โโโ custom-error.html
โ โโโ index.html
โโโ application.properties
3.์ฝ๋ ๊ตฌ์ฑ
CustomException.java
package com.example.demo.global.exception;
public class CustomException extends RuntimeException{
public CustomException(String message) {
super(message);
}
}
TestController.java
package com.example.demo.controller;
import com.example.demo.global.exception.CustomException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class TestController {
@GetMapping("/")
public String index() {
return "index";
}
@GetMapping("/test/error")
public String throwCustomError() {
throw new CustomException("ํ
์คํธ์ฉ ์ฌ์ฉ์ ์ ์ ์์ธ์
๋๋ค.");
}
@GetMapping("/test/null")
public String throwNullPointer() {
String x = null;
x.length(); // NullPointerException
return "index";
}
// 404 ๊ฐ์ ์ ๋ (์๋ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ)
@GetMapping("/test/404")
public String force404() {
return "redirect:/์๋ํ์ด์ง";
}
// 500 ๊ฐ์ ์ ๋ (Exception ๋ฐ์)
@GetMapping("/test/500")
public String force500() {
throw new RuntimeException("๊ฐ์ ๋ก ๋ฐ์์ํจ 500 ์๋ฒ ์๋ฌ์
๋๋ค.");
}
}
GlobalExceptionHandler.java
package com.example.demo.global.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
@ControllerAdvice
public class GlobalExceptionHandler {
/*@ExceptionHandler(CustomException.class)
public ResponseEntity<String> handleCustomException(CustomException ex){
return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception ex){
return new ResponseEntity<>("์๋ฒ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค:" + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}*/
@ExceptionHandler(CustomException.class)
public ModelAndView handleCustomException(CustomException ex) {
ModelAndView mav = new ModelAndView("custom-error"); // templates/custom-error.html
mav.addObject("message", ex.getMessage());
mav.addObject("redirectUrl", "/");
mav.addObject("delay", 3); // 3์ด ๋ค ์ด๋
return mav;
}
@ExceptionHandler(Exception.class)
public ModelAndView handleGeneralException(Exception ex) {
ModelAndView mav = new ModelAndView("custom-error");
mav.addObject("message", "์๊ธฐ์น ๋ชปํ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: " + ex.getMessage());
mav.addObject("redirectUrl", "/");
mav.addObject("delay", 5);
return mav;
}
@ExceptionHandler(NoHandlerFoundException.class)
public ModelAndView handle404(NoHandlerFoundException ex) {
ModelAndView mav = new ModelAndView("custom-error");
mav.addObject("message", "์กด์ฌํ์ง ์๋ ํ์ด์ง์
๋๋ค. ์
๋ ฅํ ์ฃผ์๋ฅผ ๋ค์ ํ์ธํด์ฃผ์ธ์.");
mav.addObject("redirectUrl", "/");
mav.addObject("delay", 5);
return mav;
}
}
custom-error.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>์ค๋ฅ ๋ฐ์</title>
<meta http-equiv="refresh"
th:content="${delay} + ';url=' + ${redirectUrl}" />
</head>
<body>
<h2>์ฃ์กํฉ๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.</h2>
<p>๊ด๋ฆฌ์์๊ฒ ๋ฌธ์ํด์ฃผ์ธ์.</p>
<p th:text="'์๋ฌ ๋ด์ฉ: ' + ${message}"></p>
<p th:text="'์ ์ ํ ' + ${delay} + '์ด ๋ค์ ๋ฉ์ธ ํ์ด์ง๋ก ์ด๋ํฉ๋๋ค.'"></p>
<p><a th:href="${redirectUrl}">์ง๊ธ ๋ฐ๋ก ์ด๋ํ๊ธฐ</a></p>
</body>
</html>
index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>๋ฉ์ธ ํ์ด์ง</title>
</head>
<body>
<h1>ํ(index) ํ์ด์ง์
๋๋ค</h1>
<p>์ด ํ์ด์ง๋ ์๋ฌ ๋ฐ์ ํ ๋ฆฌ๋ค์ด๋ ํธ๋๋ ๊ณณ์
๋๋ค.</p>
</body>
</html>
application.properties
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=false
4.ํ ์คํธ ๋ฐฉ๋ฒ
- /test/error: ์ฌ์ฉ์ ์ ์ ์์ธ ๋ฐ์
- /test/null: ์ผ๋ฐ ์์ธ (NullPointerException) ๋ฐ์
- ๋ ๋ค ์๋ฌ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ , 3์ด ํ ๋ฉ์ธ ํ์ด์ง(/)๋ก ์ด๋
5. ๊ฒฐ๋ก
์ด ๋ฐฉ์์ Spring Boot MVC ํ๊ฒฝ์์ ์ฌ์ฉ์์๊ฒ ์น์ ํ๊ฒ ์์ธ๋ฅผ ์๋ฆฌ๊ณ , ์๋์ผ๋ก ์์ ํ ๊ฒฝ๋ก๋ก ์ ๋ํ ์ ์๋ ์์ธ ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ด๋ค.
๋ฉ์์ง, ์ด๋ ๊ฒฝ๋ก, ์ง์ฐ ์๊ฐ ๋ฑ์ ์ํฉ์ ๋ง๊ฒ ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ, ํฅํ ๊ณตํต ์๋ฌ ์๋ต ํฌ๋งท์ผ๋ก ๋ฐ์ ์ํฌ ์ ์๋ค.
๋ฐ์ํ