728x90
exception handler
- 컨트롤러 클래스의 메서드에서
@ExceptionHandler(value = 처리할예외.class)
- 해당 컨트롤러 내에서 처리하고 싶은 예외처리에 대한 메서드를 생성 후, 애너테이션을 붙여준다.
- 하나의 컨트롤러 클래스에서 발생하는 예외 처리를 한다.
- target : 어디서 사용할 것인지 명시. 메서드에서 사용될 것이다.
- 컨트롤러 레이어에서 발생한 예외처리
- 예외 발생
@GetMapping("exc_in_controller")
public void controllerException() {
throw new NullPointerException(); // controller에서 NullPointerException 예외발생 -> @ExceptionHandler(value = NullPointerException.class) 선언된 메서드에서 처리된다.
}
- 예외 처리
@GetMapping("/check/exception/null")
@ExceptionHandler(value = NullPointerException.class)
public String nullException() throws Exception{
// ...
return "error/null";
}
- 서비스 레이어에서 발생한 예외처리
- 예외 발생
// controller
@GetMapping("exc_in_service")
public void serviceException() {
System.out.println("스테디 ");
statisticService.makeException();
// service에서 ArrayIndexOutOfBoundsException 예외발생 -> 결국 컨트롤러에서 예외 발생된 것과 동일
}
// service
public class StatisticService {
public void makeException() throws ArrayIndexOutOfBoundsException{
throw new ArrayIndexOutOfBoundsException();
}
}
- 예외 처리
@GetMapping("check/exception/oob")
@ExceptionHandler(value = ArrayIndexOutOfBoundsException.class)
public String oobException() throws Exception{
// ...
return "error/oob";
}
- 레포지터리 레이어에서 발생한 예외처리
- 2와 동일하게 throw하여 처리
- 예외 발생
// controller
@GetMapping("exc_in_repository")
public void repositoryException() {
statisticService.makeExceptionInRepository();
// service->repository에서 throws로 ArrayIndexOutOfBoundsException 예외발생 -> 결국 컨트롤러에서 예외 발생된 것과 동일
}
public void makeExceptionInRepository() throws ArrayIndexOutOfBoundsException{
try {
statisticRepository.makeExceptionInRepository();
}catch (Exception e){
throw new ArrayIndexOutOfBoundsException();
}finally {
throw new ArrayIndexOutOfBoundsException();
}
}
// repository
@Repository
public class StatisticRepository {
public Exception makeExceptionInRepository() throws ArrayIndexOutOfBoundsException{
throw new ArrayIndexOutOfBoundsException();
}
}
controller advice
- 모든 컨트롤러에 대해서 예외처리 가능
- @Controller인 컨트롤러 클래스애서 발생하는 예외를 처리한다.
- 전역 예외 처리 가능
- 컨트롤러 클래스에서 예외 발생
@Controller
public class IOExceptionTestController {
@GetMapping("/make_io_exception")
public void createIOException() throws IOException{
throw new IOException(); // @ControllerAdvice 호출됨
}
}
- @ControllerAdvice 선언된 컨트롤러 클래스에서 예외 처리하도록 만듦
@Slf4j
@ControllerAdvice
public class ErrorControllerAdvice {
@ResponseStatus(HttpStatus.FORBIDDEN)
@ExceptionHandler(IOException.class) // 처리하고 싶은 exception
public String handle(IOException exception, HttpServletRequest request){
System.out.println("@ControllerAdvice : IOException");
return "error/error";
}
}
- 1에서 /make_io_exception를 요청하면 2 클래스에서 예외처리를 해줌
자주 사용되는 방법
제일 부모 예외 클래스를 상속받은 커스텀 예외 클래스를 만듦.
이 예외에 대한 처리를 해서 모든 예외에 처리.
ResponseStatus
으로 에러의 이유를 숨김controller advice, error controller 순서
에러와 예외의 차이
- 에러 : 컴퓨터의 컴파일링 과정에서 코드 상의 잘못된 점. 코드가 잘못되어 실행되지 않음.
- 예외 : 개발자가 예외 상황에서 처리해주는 것. 실행 도중 문제(예외)가 발생하더라도 대응 코드를 작성(예외 처리)하여 예방 가능하다.
@ResponseStatus
커스텀 예외 생성 및 예외 처리
- 커스텀 예외 클래스 생성
- 어떤 부모 클래스를 상속받게 만듦.
- 이 예제에서는 RuntimeException을 상속받음
@Getter
@Slf4j
public class CustomExceptionTemp extends RuntimeException{
private HttpStatus httpStatus;
private String message;
public CustomExceptionTemp (HttpStatus httpStatus, String message){
this.httpStatus = httpStatus;
this.message = message;
}
}
- 컨트롤러 메서드에서 예외 발생 시, 커스텀 예외를 발생시키도록 만듦.
@Controller
@Log4j2
public class CustomExceptionController {
// custom 예외 발생
@GetMapping("find-member-info")
public ResponseEntity<?> findMemberInfo(){
throw new CustomExceptionTemp(HttpStatus.NOT_FOUND, "회원이 존재하지 않습니다.");
}
// RuntimeException 예외 발생 -> CustomExceptionTemp 발생
@GetMapping("find-member-info-2")
public ResponseEntity<?> findMemberInfo_2(){
try{
log.info("강제 RuntimeException invoke > catch > 생성한 CustomException throw > advice가 처리");
throw new RuntimeException();
}catch(Exception e){
throw new CustomExceptionTemp(HttpStatus.NOT_FOUND, "회원이 존재하지 않습니다.");
//
}
}
}
- @ControllerAdvice 클래스의 @ExceptionHandler 선언한 메서드를 생성
@Slf4j
@Log4j2
@ControllerAdvice
public class ErrorControllerAdvice {
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(CustomExceptionTemp.class)
public String handle(CustomExceptionTemp exception, HttpServletRequest request){
log.info("@ControllerAdvice : CustomExceptionTemp");
return "error/error";
}
}
- localhost:포트/find-member-info-2 요청 시, 로그에 다음과 같이 출력됨
- 참고로 CustomException 예외가 발생한 컨트롤러 클래스 내부에 해당 예외에 대한 @ExceptionHandler가 존재한다면 그 메서드가 @ControllerAdvice보다 먼저 실행된다.
728x90
'TIL' 카테고리의 다른 글
[TIL] 모든 개발자를 위한 HTTP 웹 기본 지식 - Section 3 (0) | 2024.04.12 |
---|---|
MyBatis foreach 반복문에 List 자료형 parameterType 사용하기 (1) | 2024.01.28 |
[TIL] Git 잘못된 브랜치에서 작업했을 때, 작업 내용을 다른 브랜치로 옮기기 (0) | 2023.11.27 |
[AWS] AWS 가입, EC2 인스턴스 생성 (0) | 2023.11.23 |
[TIL] EL, JSTL Core, Format 태그 (0) | 2023.11.16 |