Today I Learned
(24.05.17)[5주차] Spring 입문 마무리(SpringBoot JPA @ExceptionalHandler)
피드백을 알게된 내용을 정리하면서 마무리하며, 알아본 내용을 추가적으로 정리했다.
Spring 입문 강의 추가학습 정리
@ControllerAdvice @ExceptionalHandler 로 예외 출력
더보기
package com.sparta.scheduler.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class SchedulerExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(e.getMessage());
}
}
- Spring Framework에서 Annotation인@ControllerAdvice @ExceptionalHandler 을 사용해서 예외가 던져지면 화면으로 그 예외를 출력할 수 있는 코드
- index.html 화면단에서 해당 내용을 받아서 alert를 통해서 오류 내용을 사용자에게 출력, 전달 할 수 있게 설계
@ControllerAdvice
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
...
- Spring MVC 모델에서 @Controller에서 발생하는 예외를 처리하는 클래스임을 표시
- 몸통안에 예외 처리를 위한 여러 메서드를 포함해서 실행시킬 수 있고, @ExceptionalHandler 를 여기서 활용 가능
- HTTP를 통해 Clinet에게 보내줄 body작성 @ResponseBody annotation이 @RestController와 다르게 없기 때문에 @ResponseBody를 클래스 안에 써야
@ExceptionHandler(예외 클래스)
- 특정 예외를 처리하기 위한 메서드를 지정해서 사용할 수 있음을 표시
- 매개변수로는 처리하려는 예외의 클래스
- 개인과제인 나만의 일정관리 서버 프로그램을 만드는데 Scheduler 에서 모든 예외를 IllegalArgumentException로 통일하여 메시지를 출력하는 방식을 채택했으므로, 매개변수를 IllegalArgumentException.class로 지정했음
- 변수로 받은 예외클래스의 예외가 발생하면 해당 메서드가 호출되어 예외를 처리하는 부분
HttpStatus
public enum HttpStatus implements HttpStatusCode {
...
- HTTP 상태코드를 받아와서 상태코드에 해당하는 상태의 상수를 정의한 enum
- value : 400 의 reasonPhrase: "Bad Request"일 경우, HttpStatus.BAD_REQUEST를 뜻하게 됨
- 워냑 양이 방대하고 Deprecated한 부분도 있기 때문에 흔히 알고 있는 상태코드별로 구분만 할 수 있도록
ExceptionHandler도 RESTful API의 영역일 수가 있을까
더보기
@ControllerAdvice
public class SchedulerExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public ResponseEntity<SchedulerResponseDto> handleIllegalArgumentException(IllegalArgumentException e) {
SchedulerResponseDto responseDto = new SchedulerResponseDto();
responseDto.setMessage(e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(responseDto);
}
}
이슈
- RESTful한 API를 위해서 DTO타입으로 반환시켜 Client로 오류 메시지를 보내려고 하는데, 그렇다면 HTTP 상태코드를 담을 수 없게 되는 문제
원인
- DTO로 반환을 할경우에는 HTTP 상태를 맞춰서 반환할 수가 없어서 ResponseEntity<> 감싸서 반환을 시켜야 할 필요가 있음
- 예외가 발생하는 거에 대해서는 굳이 RESTful하게 만들지 않아도 상관이X API 단에서의 Docker Swagger관련이 전혀 아니기 때문
해결
@ControllerAdvice
public class SchedulerExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ExceptionResponseDto> handleIllegalArgumentException(IllegalArgumentException e) {
ExceptionResponseDto exceptionResponseDto = new ExceptionResponseDto();
exceptionResponseDto.setMessage(e.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(exceptionResponseDto);
}
}
- 따라서 그냥 ResponseEntity<SchedulerResponseDto>를 써도무관.
- 단, 만약 DTO가 엄청나게 많아질 경우엔, 모든 DTO를 다 감싸서 위처럼 ExceptionHandler로 만들어야 해결할 가능성이 존재
- 즉, 감싸서 DTO를 내보낼거면 그냥, 새로운 오류메시지 DTO를 만들어서 사용하는 것
- 일종의 CommonDTO를 만들어 내서 사용할 수 있도록 하면 됨
개인 과제도 피드백 받아 계속 진행이 될것!
다음주는 심화과정으로 가니, 계속 복습하면서 잊지말고 가져가야 할 듯.
'Today I Learned' 카테고리의 다른 글
(24.05.20)[6주차] compare, compareTo 메서드 비교 & 사용자 정의 Comparator 활용 (0) | 2024.05.20 |
---|---|
(24.05.18)[5주차] WIL (0) | 2024.05.18 |
(24.05.16)[5주차] Spring 입문 강의 02 (0) | 2024.05.16 |
(24.05.14)[5주차] Spring 입문 강의 01 (0) | 2024.05.14 |
(24.05.13)[5주차] 런타임 이슈 by NumberFormatException 예외 (0) | 2024.05.13 |