Spring boot

Bank App 만들기 - Exception Handler 처리(HTTP 상태 코드?)

햄발자 2024. 9. 26. 17:26

 

 

 

학습 목표 

1. @ControllerAdvice, @RestControllerAdvice 는 뭘까? 
2. @ControllerAdivce  와 @RestControllerAdivce 에 차이점을 이해 하자. 
3. 사용자 정의 예외 클래스를 만들기 
4. @ControllerAdvice 구현해 보기 
5. 에러 페이지 코드 수정 (errorPage.jsp) 
6. 직업 예외 발생해보기

 

 

 

1. @ControllerAdvice, @RestControllerAdvice 는 뭘까?

 

 

HTTP 통신을 통해 예외 상황을 클라이언트에게 알려주는 방법은 여러 가지가 있으며, 이들을 적절히 사용하는 것이 중요합니다.

@ControllerAdvice와 @RestControllerAdvice는 Spring Framework에서 제공하는 어노테이션들로, 애플리케이션 전역에 걸쳐 발생하는 예외를 효과적으로 관리하고 처리하는 데 사용됩니다. 이들은 일종의 "예외 처리의 중앙 집중화"를 가능하게 해주며, 애플리케이션 내 여러 컨트롤러나 서비스에서 공통적으로 발생할 수 있는 예외를 한 곳에서 관리할 수 있게 해줍니다.

 

 

 

 

2. @ControllerAdivce 와 @RestControllerAdivce 에 차이점을 이해 하자.

 

@ControllerAdvice와 @RestControllerAdvice 차이점

  • @ControllerAdvice: 이 어노테이션은 주로 @Controller 또는 @RequestMapping 어노테이션이 적용된 클래스(즉, MVC 컨트롤러)에서 발생하는 예외를 처리하기 위해 사용됩니다. HTML 뷰를 반환하는 전통적인 웹 애플리케이션에서 주로 사용됩니다.
  • @RestControllerAdvice: @ControllerAdvice와 유사한 기능을 제공하지만, @RestController에서 발생하는 예외를 처리하는 데 특화되어 있습니다. 즉, RESTful 웹 서비스에서 JSON이나 XML 같은 응답을 반환할 때 사용됩니다. 사실상, @RestControllerAdvice는 @ControllerAdvice에 @ResponseBody를 추가한 것과 동일한 효과를 제공하여, 응답 본문에 직접 데이터를 매핑할 수 있습니다.

 

@ControllerAdvice와 @RestControllerAdvice 차이점

  • @ControllerAdvice: 이 어노테이션은 주로 @Controller 또는 @RequestMapping 어노테이션이 적용된 클래스(즉, MVC 컨트롤러)에서 발생하는 예외를 처리하기 위해 사용됩니다. HTML 뷰를 반환하는 전통적인 웹 애플리케이션에서 주로 사용됩니다.
  • @RestControllerAdvice: @ControllerAdvice와 유사한 기능을 제공하지만, @RestController에서 발생하는 예외를 처리하는 데 특화되어 있습니다. 즉, RESTful 웹 서비스에서 JSON이나 XML 같은 응답을 반환할 때 사용됩니다. 사실상, @RestControllerAdvice는 @ControllerAdvice에 @ResponseBody를 추가한 것과 동일한 효과를 제공하여, 응답 본문에 직접 데이터를 매핑할 수 있습니다.

 

예시 코드 확인 - 1

ControllerAdvice 에서 데이터를 반환하는 예시 코드

 

GlobalControllerAdvice.java

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = ResourceNotFoundException.class)
    @ResponseBody
    public ResponseEntity<Object> handleResourceNotFoundException(ResourceNotFoundException ex) {
        // 에러 메시지와 함께 404 상태 코드를 반환
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}

 

예시 코드 확인 - 2

RestControllerAdvice 에서 반환

GlobalControllerAdvice.java

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = ResourceNotFoundException.class)
		// @ResponseBody 사용 안해도 됨(데이터를 반환 처리 함) 
    public ResponseEntity<Object> handleResourceNotFoundException(ResourceNotFoundException ex) {
        // 에러 메시지와 함께 404 상태 코드를 반환
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }
}

 

 

3. 사용자 정의 예외 클래스를 만들기

RuntimeException은 프로그램의 실행 도중 발생하는 예외를 나타냅니다.

컴파일 시 예외가 아닌 실행 시 예외로 분류되며, 따로 try-catch 블록으로 처리하지 않아도 컴파일러가 오류로 인식하지 않습니다. 예시로는 NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException 등이 있습니다.

여기서는 RuntimeException 확장해서 사용자 정의 예외 클래스를 만들어 봅니다.

 

 

위 그림처럼 패키지와 자바 파일을 만들어 주세요 (handler/GlobalControllerAdivce.java 파일 생성)

  • handler/GlobalControllerAdivce.java 파일 생성
  • handler/exception 패키지 생성
  • handler/exception/UnAuthorizedException 자바 파일 생성

: UnAuthorizedException 클래스는 인증이 안된 사용자가 인증이 필요하 서비스에 접근 요청을 할 때 예외를 발생 시킬 사용자 정의 예외 클래스를 설계 합니다.


test1controller.java

package com.tenco.bank.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.tenco.bank.repository.model.User;

// Controller -> String (뷰리졸버 동작 --> JSP 파일 찾아서 렌더링 처리 한다.)
// RestController --> 데이터를 반환 처리
@RestController // Controller + REST API 
public class Test1Controller {
	
	// localhost:8080/test1
	@GetMapping("/test1")
	public User test1() {
		// Gson --> JSON 형식으로 반환 --> String 응답 처리
		return User.builder().username("길동").password("asd123").build();
		
	}

}

 

 


test1controller.java

package com.tenco.bank.controller;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.mysql.cj.exceptions.UnableToConnectException;
import com.tenco.bank.handler.exception.UnAuthorizedException;
import com.tenco.bank.repository.model.User;

// Controller -> String (뷰리졸버 동작 --> JSP 파일 찾아서 렌더링 처리 한다.)
// RestController --> 데이터를 반환 처리
@RestController // Controller + @ResponseBody 
public class Test1Controller {
	
	// localhost:8080/test1
	@GetMapping("/test1")
	public User test1() {
		// Gson --> JSON 형식으로 반환 --> String 응답 처리
		
		try {
			
			int result = 10 / 0;
		} catch (Exception e) {
			throw new UnAuthorizedException("인증이 안된 사용자 입니다.", HttpStatus.UNAUTHORIZED);
		}
		return User.builder().username("길동").password("asd123").build();
		
	}

}