[Spring] 스프링의 예외처리
1. @ControllerAdvice와 @RestControllerAdvice
@ControllerAdvice는 @Controller / @RestController 컨트롤러에서 관련된 예외처리가 구현된 클래스를 나타내는 어노테이션이다. 해당 어노테이션이 붙은 클래스의 예외처리 메소드는 예외가 발생하면 오류페이지, 혹은 JSON 응답을 제공할 수 있다. 반면에 @RestControllerAdvice는 @RestController 클래스 관련된 예외처리가 구현된 클래스를 나타내는 어노테이션이다. 이름에서 알 수 있듯이 예외가 발생하면 JSON 응답만 제공할 수 있다.
ControllerAdvice를 사용하는 이유는 컨트롤러에서 던져지는 예외들을 일괄적으로 처리하기 위해서이다. ControllerAdvice의 예외핸들러 메소드에는 @ExceptionHandler를 사용하는데, 예외를 종류별로 처리할 수 있게 된다. 예외핸들러 메소드는 크게 두 가지로 나뉜다.
- 에러 페이지로 내부이동하는 메소드(내부이동)
- 오류응답데이터가 전달되게 하는 메소드(JSON 응답)
2. 예외처리 핸들러 메소드 예시
- 예외발생 시 jsp 경로로 내부이동하는 예외처리 핸들러 메소드이다.
@ExceptionHandler(예외클래스명.class)
public String handle예외클래스명(예외클래스 e) {
return "오류정보를 표시하는 jsp 페이지 경로";
}
- @ResponseBody
- ResponseBody 어노테이션은 응답메세지의 바디부에 리턴하는 값을 전달한다.
- 예외발생 시 오류메세지(JSON 텍스트 데이터)를 응답으로 제공하는 예외처리 핸들러 메소드이다.
@ExceptionHandler(예외클래스명.class)
public @ResponseBody ResponseDto<?> handle예외클래스명(예외클래스 e)
ResponseDto(?) response = new ResponseDto<>();
response.setStatus("FAIL");
response.setMessage(e.getMessage);
return response;
}
// 위의 예외처리 메소드는 {"status":"FAIL", "error": "오류 메세지 내용", "items": null}을 응답으로 보낸다.
3. 사용자 정의 예외클래스 구현
- RuntimeException을 상속받아 사용자정의 예외클래스를 구현한다.
public class CustomException extends RuntimeException { private static final long serialVersionUID = 9040654718873050613L; public CustomException(String message) { super(message); } }
- 1번에서 구현한 사용자정의 예외클래스를 상속받아서 구체적인 예외클래스를 구현한다.
public class LoginErrorException extends CustomException { private static final long serialVersionUID = -7799696001358188839L; public LoginErrorException(String message) { super(message); } }
- 2번에서 구현한 에러를 처리하는 서비스 메소드를 한번 살펴보자!
@Service public class UserService { @Autowired UserDao userDao; public User login(String id, String password) { // 회원정보 User user = userDao.getUserById(id); if (user == null) { throw new LoginErrorException("회원정보가 존재하지 않습니다."); } if ("Y".equals(user.getDisabled())) { throw new LoginErrorException("탈퇴처리된 회원 아이디입니다."); } if (!password.equals(user.getPassword())) { throw new LoginErrorException("비밀번호가 일치하지 않습니다."); } // 인증된 사용자 정보를 반환 return user; } }
- 2번에서 정의한 예외클래스에 대한 예외처리 핸들러 메소드를 정의한다.
@ControllerAdvice public class ExceptionHandlerControllerAdvice { @ExceptionHandler(LoginErrorException.class) public String handleLoginErrorException(LoginErrorException e, Model model) { model.addAttribute("error", e.getMessage()); return "loginform.jsp"; } }