본문 바로가기

JAVA

Java & SpringBoot로 시작하는 웹 프로그래밍 : 자바 인강 - 8주차

예외처리 실습

 

jsp파일 만들기

views - New -Other

 

error.jsp

<%@ page contentType="text/html;charset=utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
	<title>error.jsp</title>
</head>
<body>
<h1>예외가 발생했습니다.</h1>
발생한 예외 : ${ex}<br>
예외 메시지 : ${ex.message}<br>
<ol>
<c:forEach items="${ex.stackTrace}" var="i">
	<li>${i.toString()}</li>
</c:forEach>
</ol>
</body>
</html>

 

ExceptionControl.java

package com.fastcampus.ch2;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller // ctrl+shift+o 자동 import
public class ExceptionController {
	@RequestMapping("/ex")
	public String main() throws Exception {
		try {
			throw new Exception("예외가 발생했습니다.");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return "error";
		}
	}
}

 

http://localhost:8080/ch2/ex 입력시 결과

예외가 잘 출력된 모습

500은 서버 에러

 

try-catch문 생성

throw문 드래그 - Surround -Try/catch Block

예외가 처리되고 error.jsp view를 보여준 모습

 

 

 

예외처리 메소드를 하나 더 만드는 경우 실습

메소드 내에서 try-catch문을 중복해서 써야하는 경우 별도의 예외처리 하는 메소르도 뺄 수 있다.

@ExceptionHandler(메소드가 처리해야할 예외 종류) 로 뺄 수 있음

메소드를 catch블록이라 생각하면 된다.

 

ExceptionController.java

package com.fastcampus.ch2;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller // ctrl+shift+o 자동 import
public class ExceptionController {
	
	@ExceptionHandler(Exception.class)
	public String catcher(Exception ex, Model m) {
		m.addAttribute("ex", ex);
		return "error";
	}
	
	@ExceptionHandler(NullPointerException.class)
	public String catcher2(Exception ex, Model m) {
		m.addAttribute("ex", ex);
		return "error";
	}
	
	@RequestMapping("/ex")
	public String main() throws Exception {
		throw new Exception("예외가 발생했습니다.");
	}
	
	@RequestMapping("/ex2")
	public String main2() throws Exception {
		throw new NullPointerException("예외가 발생했습니다.");
	}
}

 

http://localhost:8080/ch2/ex입력시 실행 결과

ex를 호출하면 Exception내에 발생해서 catcher라는 메소드가 예외처리 해주고

ex2를 호출하면 NullPointerException내에 발생해서 catcher2라는 메소드가 예외처리 

 

m.addAttribute로 ex를 주면 메소드한테 자동으로 매개변수로 예외 정보가 넘어가 view로 전달

 

처리하고 싶은 예외 종류를 적어주고 그에 대한 메소드를 만들어주면 된다.

단, ExceptionHandler 메소드는 Controller 내에서만 쓸 수 있다.

 

 

여러 Controller에서도 공통으로 예외처리 할 수 있게 바꿔보기

GlobalCatcher.java

package com.fastcampus.ch2;

import java.io.FileNotFoundException;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;

@ControllerAdvice
public class GlobalCatcher {

	@ExceptionHandler({NullPointerException.class, FileNotFoundException.class})
	public String catcher2(Exception ex, Model m) {
		m.addAttribute("ex", ex);
		return "error";
	}
	
	@ExceptionHandler(Exception.class)
	public String catcher(Exception ex, Model m) {
		m.addAttribute("ex", ex);
		return "error";
	}
}

ExceptionController2.java

package com.fastcampus.ch2;

import java.io.FileNotFoundException;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller 
public class ExceptionController2 {
	
	@RequestMapping("/ex3")
	public String main() throws Exception {
		throw new Exception("예외가 발생했습니다.");
	}
	
	@RequestMapping("/ex4")
	public String main2() throws Exception {
		throw new NullPointerException("예외가 발생했습니다.");
	}
}

예외처리하는 메소드들을 별도의 클래스에 넣어놓고 @ControllerAdvice라고 붙이기만 하면

이 @ControllerAdvice밑의 메소드들이 모든 Controller에서 발생하는 예외를 다 처리하게 된다.

ExceptionController2에는 예외처리하는 메소드가 없는데 여기서 발생시킨 예외를 

GlobalCatcher가 처리하는지 보기

 

http://localhost:8080/ch2/ex3 입력시 실행 결과

Controller안에는 예외처리 메소드가 없지만 예외 처리된 이유

: GlobalCatcher클래스의 catcher메소드에서 예외를 처리했기 때문

 

결국, 공통적으로 처리할 예외를 별도의 GlobalCatcher라는 클래스에 메소드를 만들어놓고

개별적으로 다르게 예외를 처리하고 싶을때는 Controller안에다가 추가적으로 

@ExceptionHandler 가 붙은 메소드를 만들면 된다.