๐ค 0. ๊ธฐ์กด์ Exception์ ํธ๋ค๋ง ํ๋ ๋ฐฉ๋ฒ
Java Application์ ๊ฐ๋ฐํ๋ฉด์, ๋ง์ Exception์ ๋ง์ฃผํ๊ฒ ๋ฉ๋๋ค. ์ด๋ฌํ Exception์ ๋ค๋ฃจ๋ ๋ฐฉ๋ฒ์ผ๋ก๋ ๋๋ถ๋ถ ์์๋ค์ํผ try-catch ๋ฌธ์ด ์์ต๋๋ค. try ๊ตฌ๋ฌธ ๋ด๋ถ์์ Exception์ด ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ ๋ฌธ์ฅ์ ์คํํ๊ณ , ํด๋น try๋ฌธ์์ ๋ฐ์ํ ์ ์๋ ์ฌ๋ฌ Exception์ ๋ํด ์ฌ๋ฌ๊ฐ์ catch ๋ฌธ์ ๋ถ์ฌ ํธ๋ค๋ง ํ ์ ์์์ต๋๋ค.
๋ฌผ๋ก , Exception์ ํธ๋ค๋งํ๊ธฐ ์ข์ ๋ฐฉ๋ฒ์ด์ง๋ง, SpringBoot์์ ๊ฐ๋ฐํ๋ฉด์ ๋ช ๊ฐ์ง ๋ถํธํ ์ ์ ๋ฐ๊ฒฌํ ์ ์์์ต๋๋ค.
์์ธ ์ฒ๋ฆฌ ๋ก์ง์ ๋ฐ๋ก ๋ถ๋ฆฌํ ์ ์๊ณ , ํญ์ try-catch ๋ธ๋ก์ผ๋ก ๋ฌถ์ด์ ๊ฐ๋ฐํด์ผ ํฉ๋๋ค. ์ ํํ ๋น์ฆ๋์ค ๋ก์ง์ ํ์ ํ๋ ค๋ฉด, ์ด๋ฌํ ์์ธ ์ํฉ์ ๋ํ ๋ก์ง์ ๋ฐ๋ก ๋ถ๋ฆฌ๋์ด ์์ด์ผ ์ข ๋ ๊ฐ์ ๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค. ๋ํ try-catch ๋ธ๋ก์ ์์ฃผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ ์ฑ์ ๋ฌธ์ ๋ ๋ฐ์ํ ์ ์๊ฒ ์ฃ . ๋ ์์ธ ์ฒ๋ฆฌ์ ๋ก์ง์ด ๋ณ๊ฒฝ๋๋ ์ํฉ์๋, ํด๋น ์์ธ ์ฒ๋ฆฌ ๋ก์ง์ด ๋ฐ๋ก ๋ถ๋ฆฌ๋์ด ์์ง ์์, ๋ชจ๋ ๋ฉ์๋์ try-catch๋ฌธ์ ์์ธ ์ฒ๋ฆฌ ๋ถ๋ถ์ ์์ ํด์ผ ํ ๊ฐ๋ฅ์ฑ์ด ์๊ธธ ์ ์์ต๋๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์, Spring์์๋ @ExceptionHandler์ @ControllerAdvice๋ฅผ ์ ๊ณตํฉ๋๋ค.
๐ค 1. @ExceptionHandler
@ExceptionHandler ์ด๋ ธํ ์ด์ ์ ์ด๋ฆ์์๋ ์ ์ ์๋ฏ์ด ์ด๋ ธํ ์ด์ ์ด ๋ฌ๋ ค์๋ ๋ถ๋ถ์ ๋ํด Exception์ด ๋ฐ์ํ๊ฒ ๋๋ฉด, ํธ๋ค๋ง์ ํ ์ ์์ต๋๋ค.
์ด๋ฌํ @ExceptionHandler๊ฐ ์๋ํ๋ ๋ฒ์๋ @Controller์ @RestController๊ฐ ๋ฌ๋ ค์๋ ๋น ๊ฐ์ฒด์ ํํด์ ์๋ํฉ๋๋ค. ์ฆ, @Service๋ @Repository๊ฐ ์ ์ฉ๋ ๋น ์์์๋ ์๋ํ ์ ์์ต๋๋ค.
์ปจํธ๋กค๋ฌ์ ํน์ Exception์ ๋ํด ํธ๋ค๋งํ ์ ์๋ ๋ฉ์๋๋ฅผ ๋ง๋ค๊ณ , ์ด ์์ @ExceptionHandler๋ฅผ ์ค์ ํ๋ ๊ฒ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
@Controller
public class Controller {
// ...
@ExceptionHandler(value = RuntimeException.class)
public ResponseEntity<String> handle(IOException ex) {
// ...
}
}
์ด๋ฐ ์์ผ๋ก ์ฌ์ฉํ๊ฒ ๋๋ฉด, Controller ๋ ๋ฒจ์์ ๋ฐ์ํ RuntimeException์ ๋ํด ํด๋น ExceptionHandler ์ด๋ ธํ ์ด์ ์ด ๋ถ์ด์๋ ๋ฉ์๋๊ฐ ํด๋น Exception์ ์ฒ๋ฆฌํ๊ฒ ๋ฉ๋๋ค.
๋ฌผ๋ก , ๋จ์ผ ์์ธ ์ฒ๋ฆฌ๊ฐ ์๋๋ผ, ์ฌ๋ฌ๊ฐ์ง Exception์ ํ ๋ฉ์๋๊ฐ ๋ค๋ฃจ๋๋ก ์ง์ํ ์๋ ์์ต๋๋ค.
@Controller
public class Controller {
// ...
@ExceptionHandler(value = {IOException.class, NullPointerException.class})
public ResponseEntity<String> handle(Exception ex) {
// ...
}
}
์์ ๊ฐ์ ์ฝ๋๋ก ์์ฑ์ ํ๊ฒ ๋๋ฉด, Controller ํด๋์ค์์ ๋ฐ์ํ IOException๊ณผ NullPointerException์ ๋ํด ํด๋น handle ํจ์๊ฐ catchํด์ ๊ฐ์ ์ฒ๋ฆฌํ๊ฒ ๋ฉ๋๋ค.
๊ณตํต์ ์ผ๋ก ๋ฐ์ํ๋ Exception์ ๋ํด์ Exception ํธ๋ค๋ฌ๋ฅผ ํตํด์ ์ฒ๋ฆฌ๋ฅผ ํ๊ฒ ๋๋ฉด, ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ผ ๋ฟ๋ง ์๋๋ผ, ๊ฐ ์์ธ ์ฒ๋ฆฌ๋ฅผ ์ฌ๋ฌ๋ฒ ์์ฑํ์ง ์์๋ ํ ํธ๋ค๋ง ๋ฉ์๋์์ ๋ค๋ฃฐ ์ ์์ผ๋ฏ๋ก ์์ฐ์ฑ์ด ๋์ฑ ๋์ด๋๊ฒ ๋ฉ๋๋ค.
๐ค 2. @ControllerAdvice
์ข ๋ ํ์ฅํด๋ณด๊ฒ ์ต๋๋ค. ํ๋์ ์ปจํธ๋กค๋ฌ๊ฐ ์๋, ์ ์ญ์ ์ผ๋ก ์ฌ๋ฌ ์ปจํธ๋กค๋ฌ์ ๋ํด์ Exception์ ๋ค๋ฃจ๊ณ ์ถ๋ค๋ฉด @ControllerAdvice๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
๋ชจ๋ Controller์ ๋ํด์ ํน์ Exception์ ํ ๋ฒ์ ์ ์ดํ๋ ค๋ฉด, ์๋ก์ด ๊ด๋ฆฌ ์ปจํธ๋กค๋ฌ๋ฅผ ์์ฑํ๊ณ @ControllerAdvice ์ด๋ ธํ ์ด์ ์ ๋ถ์ฌ์ค๋๋ค.
@ControllerAdvice
public class ControllerAdvice{
// ..
}
์ด๋ฐ์์ผ๋ก ์๋ก์ด ControllerAdvice ํด๋์ค๋ฅผ ์์ฑํ๊ณ ์ด๋ ธํ ์ด์ ์ ๋ถํ์ค๋ค๋ฉด, ๋ชจ๋ Controller์์ ๋ฐ์ํ๋ Exception์ ๋ํด ์ ์ญ์ ์ผ๋ก ๊ด๋ฆฌํ ์ ์๊ฒ ๋ฉ๋๋ค.
์ด ControllerAdvice๊น์ง Exception์ด ์ ๋ฌ๋์๋ค๋ฉด, ์ด ์ ๋ฌ๋ Exception์ ๋ํด ํธ๋ค๋ง ํ ๋ฉ์๋๊ฐ ํ์ํฉ๋๋ค.
๊ทธ๋ฌํ ๋ฉ์๋๋, ์์์ ์ค๋ช ํ @ExceptionHandler๋ฅผ ํตํด ๊ด๋ฆฌํ๋ฉด ๋ฉ๋๋ค.
@RestContollerAdvice
public class ControllerAdvice{
@ExceptionHandler(value = NullPointerException.class)
public ResponseEntity<String> handle(Exception ex){
// ...
}
}
์์ ๊ฐ์ ํ์์ผ๋ก ์์ฑํ๋ฉด ๋ชจ๋ ์ปจํธ๋กค๋ฌ์ ๋ํด์ NullPointerException์ด ๋ฐ์ํ๊ฒ ๋๋ค๋ฉด, ํด๋น ํด๋์ค์ handle ํจ์๋ก ์ ๋ฌ๋๊ณ , ํด๋น handle ๋ฉ์๋์ ๋ก์ง์ ๋ฐ๋ผ์ ์ฒ๋ฆฌ๋ ์ ์์ต๋๋ค.
@ContollerAdvice์ธ์๋ @RestControllerAdvice๊ฐ ์๋๋ฐ, ์ด๊ฒ์ @Controller์ @RestController์ ์ฐจ์ด์ ์ ์ฌํฉ๋๋ค.
@RestControllerAdvice์๋ @ResponseBody ์ด๋ ธํ ์ด์ ์ด ํฌํจ๋์ด ์๋ฐ๊ฐ์ฒด๋ฅผ HTTP ์์ฒญ์ ๋ฐ๋๋ด์ฉ์ผ๋ก ๋งคํํ์ฌ ํด๋ผ์ด์ธํธ๋ก ์ ์กํ๊ฒ ๋ฉ๋๋ค.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ControllerAdvice
@ResponseBody
public @interface RestControllerAdvice {
// ...
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
// ...
}