BankApp - Exception Handler

Gun·2023년 9월 18일

Spring Boot - BankApp

목록 보기
10/25
💡 학습목표
   1. Exception Handler 처리
   2. @ControllerAdvice 와 @RestControllerAdvice의 차이점 이해하기
   3. 사용자 정의 예외 클래스를 만들어 보기

1. Exception Handler 처리

💡 Exception Handler

   스프링 MVC 의 중요한 구성 요소 중에 하나로 AOP 기반에 개념과는 약간 다른 개념 입니다. 
   구현하는 방법 중 하나는 @ExcetptionHandler 어노테이션을 사용하고 이 어노테이션은 
   예외가 발생한 메서드를 구현하고, 처리할 예외 타입을 지정합니다.

2. @ControllerAdvice 와 @RestcontrollerAdvice의 차이점 이해하기

💡 @ControllerAdvice 와 @RestcontrollerAdvice

   @ControllerAdvice와 @RestControllerAdvice는 모두 예외 처리를 담당하는 클래스에 
   붙는 어노테이션으로 스프링에서 예외 처리를 담당하는 핵심적인 요소 중 하나입니다. 
   그러나 두 어노테이션에 차이점은 반환 타입과 기본 응답 형태 입니다. 

   @ControllerAdvice 어노테이션은 View 렌더링을 위해 ModelAndView 형태로 
   객체를 반환하도록 기본 설정이 되어 있습니다. 
   즉, 요청에 대한 응답이 view 형태로 전달되며, JSP 와 같은 템플릿 엔진을 사용할 수 있습니다. 

   반면에 @RestControllerAdvice RESTfull 웹 서비스에서 사용하기 적합한 형태로
   응답 처리가 되며 응답에 형태는 JSON, XML 형태로 반환이 됩니다. 

사용자 정의 예외 클래스 만들어 보기 -1

CustomPageException.java


package com.tencoding.bank.handler.exception;

import org.springframework.http.HttpStatus;

public class CustomPageException extends RuntimeException{

	private HttpStatus status;
	
	public CustomPageException(String message, HttpStatus status) {
		super(message);
		this.status = status;
	}
}

사용자 정의 예외 클래스 만들어 보기 - 2

CustomRestfulException.java


package com.tencoding.bank.handler.exception;

import org.springframework.http.HttpStatus;

import lombok.Getter;

// 클래스 정의
@Getter // IoC 대상이 아니다. (필요할 때 직접 new 할 예정)
public class CustomRestfulException extends RuntimeException{
	
	private HttpStatus status;
	
	public CustomRestfulException(String message, HttpStatus status) {
		super(message);
		this.status = status;
	}
}

package com.tencoding.bank.handler;

import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.tencoding.bank.handler.exception.CustomRestfulException;

/**
 * 예외 발생 시 (Json, Xml)
 * 데이터를 가공해서 내려 줄 수 있다.
 * 
 * 
 */

@RestControllerAdvice // IoC 대상 + Aop 대상
public class MyRestfulExceptionHandler {

	// 모든 예외가 발생했을 때
	@ExceptionHandler(Exception.class)
	public void exception(Exception e) {
		System.out.println("=== 예외 발생 확인 ===");
		System.out.println(e.getMessage());
		System.out.println("----------------------");
	}
	
	// 사용자 정의 예외 클래스 활용
	@ExceptionHandler(CustomRestfulException.class)
	public String basicException(CustomRestfulException e) {
		StringBuffer sb = new StringBuffer();
		sb.append("<script>");
		sb.append("alert(' "+ e.getMessage() +" ');"); // 문자열 안에 반드시 ;붙이기
		sb.append("history.back();");
		sb.append("</script>");
		return sb.toString();
	}
}

💡 사용자 정의 예외 클래스 설계
   ControllerAdvice 설계 
errorPage.jsp 사용 

실제 적용 ControllerAdvice - Handler 처리


package com.tencoding.bank.handler;

import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import com.tencoding.bank.handler.exception.CustomPageException;

/**
 * View 렌더링을 위해 ModelAndView
 * 객체를 반환하도록 설계할 때 사용
 * 예외 page를 리턴하도록 설계
 */

@ControllerAdvice // IoC의 대상
@Order(2) 
public class MyPageExceptionHandler {
	
	// 모든 예외가 발생했을 때
	@ExceptionHandler(Exception.class)
	public void exception(Exception e) {
		System.out.println("=== 예외 발생 확인 ===");
		System.out.println(e.getMessage());
		System.out.println("----------------------");
	}
	
	// 사용자 정의 클래스 활용
	@ExceptionHandler(CustomPageException.class)
	public ModelAndView handleRunTimePageException(CustomPageException e) {

		// ModelAndView 활용 방법 - 페이지 명시해야 함
		ModelAndView modelAndView = new ModelAndView("errorPage");
		modelAndView.addObject("statusCode", HttpStatus.NOT_FOUND.value());
		modelAndView.addObject("message", e.getMessage());
		return modelAndView;
	}
	
}

errorPage.jsp


&&&&<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ page isErrorPage="true" %>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>에러 페이지</h1>
    <p>에러 코드 : ${statusCode}</p>
    <p>에러 메세지 : ${message}</p>
</body>
</html>

0개의 댓글