예외발생 상황마다 try-catch 블럭을 묶을 필요 없이
예외발생 처리메서드를 따로 빼내어 예외처리 할 수 있음
1.예외종류에 따라 다르게 받을 수 있음
2.애너테이션에 처리할 예외 여러개 추가 가능
3.만약 Exception의 자식 예외가 발생했는데 처리 메서드 없는 경우, 조상인 Exception처리 메서드가 예외처리함
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 ExceptionController {
//예외가 발생하는 상황에 공통적으로 사용하는 메서드
//try-catch일일히 안적어도 됨
@ExceptionHandler(Exception.class)
public String cacther(Exception ex, Model m) {
m.addAttribute("ex", ex);
return "error";
}
//예외 종류에 따라 다르게 받을 수 있음 (NullPointerException인 경우)
//애너테이션에 처리할 예외 경우 여러개 추가 가능
//만약 Exception의 자식 예외가 발생했는데 처리할 메서드 없는 경우
//조상인 Exception처리 메서드가 예외 처리함
@ExceptionHandler(NullPointerException.class)
public String cacther2(Exception ex, Model m) {
System.out.println("ExceptionController: NullPointerException 처리");
//=> ControllerAdvice 애너테이션보다 가까운 컨트롤러가 예외처리를 우선함을 확인
m.addAttribute("ex", ex);
return "error";
}
/*
* @ExceptionHandler(FileNotFoundException.class) public String
* cacther3(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("예외가 발생하였습니다.");
}
@RequestMapping("/ex3")
public String main3() throws Exception{
throw new FileNotFoundException("예외가 발생하였습니다.");
}
}
@controllerHandler 예외처리 메서드는 동일 컨트롤러 안에서만 사용 가능
예시의 경우에도 ExceptionController.java에 NullPointerException처리메서드 있으나,
ExceptionController2.java에 처리 메서드 없으므로 500error발생
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
public class ExceptionController2 {
//예외처리 메서드는 동일한 컨트롤러 안에서만 사용가능함
/*
* @ExceptionHandler(NullPointerException.class) public String
* cacther2(Exception ex, Model m) { m.addAttribute("ex", ex); return "error"; }
*/
/*
* @RequestMapping("/ex3") public String main() throws Exception{ throw new
* Exception("예외가 발생하였습니다."); }
*/
@RequestMapping("/ex4")
public String main2() throws Exception{
throw new NullPointerException("예외가 발생하였습니다.");
}
}
해당 애너테이션을 붙이고 예외처리 메서드를 작성하면
이는 모든 컨트롤러에서 사용가능한 예외처리 메서드가 된다
애너테이션 옆에 패키지명 기입하면 해당 패키지 내에서만 사용가능하고
패키지명 기입하지 않으면 모든 패키지에서 사용가능한 예외처리 메서드가 됨
package com.fastcampus.ch2;
import java.io.FileNotFoundException;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice("com.fasrcampus.ch2")
//아무것도 안적으면 모든 패키지의 예외처리
//적으면 해당 패키지안의 예외만 처리
public class GlobalCatcher {
//@ControllerAdvice 애너테이션을 붙여주면
//모든 컨트롤러에서 사용가능한 예외처리 메서드가 된다
//만약 해당 컨트롤러와 글로벌 컨트롤러 둘 다에 발생한 에러를 처리하는 메서드가 있다면?
//가까운 메서드가 처리함 => 개별 컨트롤러가 처리함
@ExceptionHandler(Exception.class)
public String cacther(Exception ex, Model m) {
m.addAttribute("ex", ex);
return "error";
}
@ExceptionHandler(NullPointerException.class)
public String cacther2(Exception ex, Model m) {
m.addAttribute("ex", ex);
return "error";
}
@ExceptionHandler(FileNotFoundException.class)
public String cacther3(Exception ex, Model m) {
m.addAttribute("ex", ex);
return "error";
}
}