πSpring/Exception
# Spring Boot μ μ μμΈ μ²λ¦¬ + μλ¬ νμ΄μ§ ν 리λ€μ΄λ νΈ κ΅¬ν μ 리
λμ§λ§
2025. 5. 29. 11:08
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 νκ²½μμ μ¬μ©μμκ² μΉμ νκ² μμΈλ₯Ό μλ¦¬κ³ , μλμΌλ‘ μμ ν κ²½λ‘λ‘ μ λν μ μλ μμΈ μ²λ¦¬ λ°©λ²μ΄λ€.
λ©μμ§, μ΄λ κ²½λ‘, μ§μ° μκ° λ±μ μν©μ λ§κ² νμ₯ κ°λ₯νλ©°, ν₯ν κ³΅ν΅ μλ¬ μλ΅ ν¬λ§·μΌλ‘ λ°μ μν¬ μ μλ€.