728x90
아래 내용은 https://github.com/beaver84/setting-test 에서 실제 소스를 확인할 수 있습니다.
- @ControllerAdvice는 Spring에서 제공하는 Annotation입니다.
- Spring 애플리케이션에서 예외 처리를 관리하는 데 사용됩니다.
- 단일 클래스 또는 하나의 메서드가 아닌 애플리케이션의 모든 클래스에서 발생하는 모든 예외를 처리할 수 있습니다.
- API 서버일 경우, 기본적으로 성공함을 가정한 API 응답을 정의하고, 그다음 Exception이 발생했을 때, 응답을 정의하는 것이 일반적이다(성공 → 실패 advice 참조)
- 200(성공)일 때, 적용 예시
@ControllerAdvice(basePackages = "com.marvrus.moon_app_api.controller.api")
public class ControllerResponseAdvise implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
ApiResponse apiResponse = new ApiResponse();
apiResponse.setSuccess(true);
apiResponse.setData(body);
return apiResponse;
}
}
- ApiResonse.class - 위에서 success, data를 getter, setter로 빼놓음, 200일 때 전용
public class ApiResponse {
private boolean success;
private Object data;
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
728x90
- (예외 처리)ApiExceptionHandler.class - 200이 아닐경우 ControllerAdvice
@ControllerAdvice
public class ApiExceptionHandler {
private Logger log = LogManager.getLogger(this.getClass());
@ExceptionHandler(ApiException.class)
protected ResponseEntity<ApiExceptionInfo> handleMethodArgumentNotValidException(ApiException e) {
log.error("API Exception : {}", e.getMessage());
for (StackTraceElement element : e.getStackTrace()) {
log.error("{}", element.toString());
}
final ApiExceptionInfo response = new ApiExceptionInfo();
response.setHttpStatus(e.getStatusCode());
response.setMessage(e.getMessage());
response.setSuccess(false);
return new ResponseEntity<>(response, e.getStatusCode());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ApiExceptionInfo> handleMethodArgumentNotValidException(
MethodArgumentNotValidException e) {
log.error("API Exception : {}", e.getMessage());
for (StackTraceElement element : e.getStackTrace()) {
log.error("{}", element.toString());
}
final ApiExceptionInfo response = new ApiExceptionInfo();
response.setHttpStatus(HttpStatus.BAD_REQUEST);
response.setMessage(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
response.setSuccess(false);
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
protected ResponseEntity<ApiExceptionInfo> handleMethodArgumentNotValidException(Exception e) {
log.error("API Exception : {}", e.getMessage());
for (StackTraceElement element : e.getStackTrace()) {
log.error("{}", element.toString());
}
final ApiExceptionInfo response = new ApiExceptionInfo();
response.setHttpStatus(HttpStatus.INTERNAL_SERVER_ERROR);
response.setMessage(e.getMessage());
response.setSuccess(false);
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
- ApiExceptionInfo.class - 200이 아닐경우, 메시지를 내려주는 DTO 정의
public class ApiExceptionInfo {
private String message;
private HttpStatus httpStatus;
private Boolean success;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public HttpStatus getHttpStatus() {
return httpStatus;
}
public void setHttpStatus(HttpStatus httpStatus) {
this.httpStatus = httpStatus;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
}
- ApiException.class - 200(정상)이 아닐경우, 실제 Api 요청의 응답 형식이 정의되어 있는 곳
public class ApiException extends HttpStatusCodeException {
public ApiException(HttpStatus statusCode) {
super(statusCode);
}
public ApiException(HttpStatus statusCode, String statusText) {
super(statusText, statusCode, statusText, null, null, null);
}
public ApiException(HttpStatus statusCode, String statusText, byte[] responseBody, Charset responseCharset) {
super(statusCode, statusText, responseBody, responseCharset);
}
public ApiException(String message, HttpStatus statusCode, String statusText, HttpHeaders responseHeaders,
byte[] responseBody, Charset responseCharset) {
super(message, statusCode, statusText, responseHeaders, responseBody, responseCharset);
}
public ApiException(HttpStatus statusCode, String statusText,
@Nullable HttpHeaders responseHeaders, @Nullable byte[] responseBody,
@Nullable Charset responseCharset) {
super(statusText, statusCode, statusText, responseHeaders, responseBody, responseCharset);
}
}
728x90
'Spring > 초기 setting' 카테고리의 다른 글
10) Spring Data Redis 셋팅 (0) | 2023.04.20 |
---|---|
9) 비밀번호 암/복호화(Encrypt/Decrypt) 설정 (0) | 2023.04.20 |
mapStruct 소개 및 활용 (0) | 2023.04.10 |
6) 스프링 시큐리티(spring-security) 적용 (0) | 2023.04.05 |
5) 스프링 시큐리티(spring-security) 개요 (0) | 2023.04.05 |