동작 과정에서 발생하는 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");
}
}
[해당 포스트 프로젝트]
'Backend > SpringBoot' 카테고리의 다른 글
[Spring Boot]Response Handling 하기-Flux (0) | 2022.07.10 |
---|---|
[Spring Boot]Response Handling 하기-MVC (0) | 2022.07.09 |
[Spring Boot] Feign Client 로그 미동작 해결 (0) | 2022.06.10 |
[Spring Boot] Gradle을 사용하여 편하게 배포하자! (0) | 2021.12.12 |
[SpringBoot] 외부 Properties File 사용하기 (0) | 2021.12.11 |