이번 시간에는 개발자가 발생시키는 Exception을 다루는 방법에 대해서 알아보도록 하겠습니다.
DDD 라는 책을 읽고 DDD를 진행하면서 도메인로직을 구현하며 올바르지 않은 접근에 대해서는 Exception을 발생시키도록 했습니다.
하지만 이러한 Exception을 클라이언트 측 프로그램에 그대로 전달할 수만은 없을 것 이며, Spring MVC에서 Exception을 다루는 방법이 존재할 것 같아 찾아본 결과 Exception을 다룰 수 있는 ExceptionHandler
라는 것을 발견하게 되었습니다.
1. @ExceptionHandler
ExceptionHandler
란 이름 그대로 예외가 발생한 요청을 처리하기 위한 핸들러입니다. Exception이 발생하게 될 경우 자동으로 정의한 Handler가 실행이 됩니다.
1.1 시나리오
실습에 앞서 간단히 현재 프로그램에서 Exception이 발생하는 상황을 설명 드리겠습니다. UserEntity
가 존재합니다. UserEntity
에는 UserInformation
과 Tickets
라는 Value를 가지고 있습니다. 이때 User는 반드시 하나의 Ticket만을 소유할 수 있습니다.
xpublic void putTicketsImagePath(String imagePath) {
verifyTicketExist();
this.ticket = Ticket.builder()
.ticketImagePath(imagePath)
.build();
}
private void verifyTicketExist() {
if(ticket != null)
throw new IllegalStateException("이미 업로드한 티켓이 존재합니다.");
}
앞서 설명드린 도메인의 제한사항에 의해 사용자의 Ticket을 업로드 하는 메소드인 putTicketsImagePath()
메소드를 실행하기 전, 이미 업로드한 Ticket이 존재하는지 확인하는 메소드인 verifyTicketExist()
라는 메소드를 실행하도록 했습니다. 여기서 주목할 점은 IllegalStateException을 반환한다는 것입니다.
1.2 IllegalStateException을 처리하는 ExceptionHandler 생성하기
xxxxxxxxxx
"/users") (
public class UserRestContoller {
private UserService userService;
public String illegalExceptionHandler(IllegalStateException exception) {
return "exception";
}
우선 위와 같이 Controller에 @ExceptionHandler
어노테이션이 부여된 method를 생성합니다.
그 후 handling 하고자 하는 Exception을 매개변수에 추가하면 끝입니다.
1.3 개발자 정의 Exception 만들기
앞서 사용한 IllegalStateException
과 같이 Java에서 기본적으로 제공해주는 Exception을 그대로 사용해도 되지만, 도메인의 제한사항에 의해 다양한 Exception이 발생하기 마련입니다. 이때는 Exception을 상속받아 개발자 정의 Exception을 생성하여 조금더 세부적인 Exception 처리를 할 수 있습니다.
xxxxxxxxxx
package com.photosend.photosendserver01.user.domain.exception;
public class UploadTicketException extends IllegalStateException {}
우선 처리하고자 하는 Exception을 이름으로 가지는 Class를 생성한 뒤, Exception을 상속 받습니다.
xxxxxxxxxx
public class UserEntity {
private void verifyTicketExist() {
if(ticket != null)
throw new UploadTicketException();
}
제한사항이 있는 도메인의 Exception을 앞서 생성한 UploadTicketException()으로 변경합니다.
xxxxxxxxxx
public class UserRestContoller {
private UserService userService;
public String uploadTicketExceptionHandle(UploadTicketException exception) {
return "이미 업로드한 티켓이 존재합니다.";
}
Controller의 ExceptionHandler의 매개변수도 앞서 생성한 UploadTicketException
으로 변경합니다.
테스트 결과입니다.
1.4 RestAPI의 Exception 처리
RestAPI
의 경우 응답 본문(ResponseBody)
에 Exception에 대한 정보를 담아줍니다. 또한 상태코드를 적절하게 변경하기 위해 ResponseEntity
를 사용합니다.
xxxxxxxxxx
public ResponseEntity uploadTicketExceptionHandler(UploadTicketException uploadTicketException) {
return ResponseEntity.badRequest().body("이미 업로드한 티켓이 존재합니다.").;
}
나머지 코드는 모두 동일하며 Handler의 returnType을 ResponseEntity
로 변경한 뒤 return 값을 ResponseEntity Builder를 이용해 적절히 생성하고 그 값을 return 하면 됩니다.
'FrameWork > Spring MVC' 카테고리의 다른 글
Spring MVC - 유연한 다중 파일업로드 핸들러 만들기 (Multipart upload) (0) | 2020.01.29 |
---|---|
SpringMVC - @RequestBody로 Timestamp 전달하기 (@JsonFormat : timezone 설정, 입력형식 정하기) (0) | 2019.07.25 |
SpringMVC - Spring JDBC에서 Mysql에 날짜/시간 데이터 입력 (3) | 2019.06.09 |
SpringMVC - 핸들러 메소드 - 8 (파일 다운로드 기능 구현, 리턴타입 : ResponseEntity) (0) | 2019.06.04 |
SpringMVC - 핸들러 메소드 - 7 (파일업로드 매개변수 : MultipartFile) (0) | 2019.05.29 |