2024. 12. 17. 23:55ㆍSpring Boot

기본적으로 Spring Boot에서 Exception이 발생하면 Basic Error Controller를 호출해서 해당 페이지가 나온다
이 페이지는 기본적으로 Execption이 발생하면 출력되도록 설정되어 있어서 기본적은 오류 내용을 표기해준다
다만 문제가 있는데
무조건 Status Code가 500으로 나오고
불필요한 내용이 많이 담기고
내용도 명확하지 않고
작동 방식이 컨트롤러를 한 번 더 호출하는 방식이라 필터나 인터셉터 관련 처리도 필요하다

package com.example.mvc.exception;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/error")
public class BasicErrorController extends AbstractErrorController {
public BasicErrorController(ErrorAttributes errorAttributes, List<ErrorViewResolver> errorViewResolvers) {
super(errorAttributes, errorViewResolvers);
}
@RequestMapping
public ResponseEntity<String> basic_error() {
return ResponseEntity.status(500).body("this is basic");
}
}

물론 커스텀을 한 Basic Error Controller를 등록 시킬 수 있긴 한데
주로 다른 방법을 통해 Exception을 처리한다.
이제 진짜로 자주 쓰이는 Exception을 다룰 때 사용하는 Exception Handler를 알아보겠다.
우선 한 Controller에서 Exception을 다룰 때는 Controller 내부에 Exception Handler를 만들어 사용하고
전역으로 다룰 때는 ControllerAdvice를 정의하고 그 안에 Exception Handler를 만들어 사용한다.
작동 방식은 등록된 Exception이 발생 시 해당 Handler를 불러서 처리하는 방식이다.
이때 부모 Exception을 등록하면 자식 Exception의 Handler가 없을 때 부모 Exception의 Handler를 부른다.
만약 Handler를 정의하지 않으면 아까 말했던 BasicErrorController을 부른다.

Exception Handler)
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.server.ResponseStatusException;
@Slf4j
@Controller
@RequestMapping("/test/exception")
public class exception_controller {
@GetMapping("/runtime/default")
public String runtime_default() {
throw new RuntimeException("runtime error test");
}
@GetMapping("/runtime/status")
public String runtime_status() {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "bad request");
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> runtime_exception(RuntimeException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage() + " from controller exception handler");
}
RestControllerAdvice)
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class global_exception_handler {
@ExceptionHandler(RuntimeException.class)
private ResponseEntity<String> runtimeExceptionHandler(RuntimeException e) {
return ResponseEntity.status(401).body(e + " from rest controller advice");
}
}
기본적으로 해당 컨트롤러에 Exception Handler가 정의 되어 있으면 그 쪽을 우선시 하고 없으면 ControllerAdvice를 찾는다.
즉 우선 순위는
컨트롤러의 Exception Handler > ControllerAdvice의 Handler > BasicErrorController이다.
'Spring Boot' 카테고리의 다른 글
| JPA란? (0) | 2024.12.01 |
|---|---|
| Spring Data DTO (0) | 2024.12.01 |
| JPA Paging (0) | 2024.11.28 |
| JPQL (0) | 2024.11.28 |
| Spring Cloud Eureka (0) | 2024.10.29 |