본문 바로가기

Backend/SpringBoot

[Spring Boot]Exception Handling 하기

동작 과정에서 발생하는 Exception을 제어하는 방법을 작성한 포스팅입니다.

 

[관련 포스트]

[활용 목적]

  • 예외 처리된 결과를 특정 포맷으로 변경하여 제공하고 싶은 경우
  • Exception 별로 별도의 동작(로그, 추가 행동)을 작성하려는 경우

[Dependencies]

dependencies {
	...
    implementation 'org.springframework.boot:spring-boot-starter-web'
    // 별도의 모듈로 만들고 프로젝트가 MVC인지 Flux 인지 모를 경우
    // implementation group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
    compileOnly 'org.projectlombok:lombok'
    ...
}

구현

CommonResult.java

@AllArgsConstructor(access = AccessLevel.PROTECTED)
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public class CommonResult implements Serializable {
    private boolean success;
    private Integer status;
    private String message;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime timestamp;

    public static CommonResult success() {
        return new CommonResult(true, HttpStatus.OK.value(), "Success", LocalDateTime.now());
    }

    public static CommonResult success(final int status) {
        return new CommonResult(true, status, "Success", LocalDateTime.now());
    }

    public static CommonResult error(final HttpStatus errorStatus) {
        return new CommonResult(false, errorStatus.value(), errorStatus.getReasonPhrase(), LocalDateTime.now());
    }

    public static CommonResult error(final int errorStatus, final String errorMessage) {
        return new CommonResult(false, errorStatus, errorMessage, LocalDateTime.now());
    }
}

SingleResult.java

@Getter
class SingleResult<T> extends CommonResult {
    private final T data;

    private SingleResult(final boolean success, final Integer status, final String message, final LocalDateTime timestamp, final T data) {
        super(success, status, message, timestamp);
        this.data = data;
    }

    public static <T>SingleResult<T> success(final T data) {
        return new SingleResult<>(true, HttpStatus.OK.value(), "Success", LocalDateTime.now(), data);
    }

    public static <T>SingleResult<T> success(final T data, final int status) {
        return new SingleResult<>(true, status, "Success", LocalDateTime.now(), data);
    }
}

ExceptionAdvice.java

@Slf4j
@RestControllerAdvice
public class ExceptionAdvice {
    @ExceptionHandler(RuntimeException.class)
    public Object handle(RuntimeException e) {
        e.printStackTrace();
        return CommonResult.error(HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(Exception.class)
    public Object handleException(Exception e) {
        e.printStackTrace();
        return CommonResult.error(HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        e.printStackTrace();
        Optional<ObjectError> first = e.getAllErrors().stream().findFirst();
        return CommonResult.error(HttpStatus.BAD_REQUEST.value(),
                first.isPresent() ? first.get().getDefaultMessage() : e.getMessage());
    }


    @ExceptionHandler(AccessDeniedException.class)
    public Object handleAccessDeniedException(AccessDeniedException e) {
        e.printStackTrace();
        return CommonResult.error(HttpStatus.UNAUTHORIZED.value(), e.getMessage());
    }

    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public Object handleHttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e) {
        e.printStackTrace();
        return CommonResult.error(HttpStatus.BAD_REQUEST.value(), "Unsupported Media Type");
    }


    @ExceptionHandler(NoHandlerFoundException.class)
    public Object handleNoHandlerFoundException(NoHandlerFoundException e) {
        e.printStackTrace();
        return CommonResult.error(HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Object handleNotSupportedMethodException(Exception e) {
        e.printStackTrace();
        return CommonResult.error(HttpStatus.METHOD_NOT_ALLOWED);
    }

    @ExceptionHandler(MissingServletRequestParameterException.class)
    public Object handleMissingRequestParameterException(Exception e) {
        e.printStackTrace();
        return CommonResult.error(HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(ServletRequestBindingException.class)
    public Object handleServletRequestBindingException(Exception e) {
        e.printStackTrace();
        return CommonResult.error(HttpStatus.BAD_REQUEST.value(), "Missing Attribute");
    }
}

[해당 포스트 프로젝트]

 

GitHub - PCloud63514/SpringSkilsExample: 스프링 부트를 사용하며 적용했던 기술들을 정리한 문서

스프링 부트를 사용하며 적용했던 기술들을 정리한 문서. Contribute to PCloud63514/SpringSkilsExample development by creating an account on GitHub.

github.com