오늘도 구현 과제 대비를 위해 스프링 공부를 했다. 오늘은 예외처리에 대해 정리해보았다.
HTTP/1.1 404 Not Found
Http에서 서버가 클라이언트에게 보내는 Response의 가장 첫줄에는 응답 코드가 있다.
Response Header의 가장 윗줄에 있는 세자리 번호가 API요청 결과를 나타내는 상태코드를 의미한다.
HTTP 상태 코드 종류
1xx : 조건부 응답. 요청을 받았으며 작업을 진행중.
2xx : 성공. 서버가 요청을 제대로 처리. 200 OK(성공)
3xx : 리다이렉션 완료. 클라이언트는 요청을 마치기 위해 추가동작(리다이렉션)을 취해야한다.
4xx : 잘못된 요청. 클라이언트 에러. 클라이언트 Request에서 오류가 났을 때.
400 Bad Request(요청 자체가 잘못됨) 403 Forbidden(접근금지) 404 Not Found(찾을수없음)
5xx : 서버 에러. 서버가 유효한 요청을 수행하지 못함.
Spring에서는 HttpStatus를 모아둔 Enum이 있어 필요할때 사용하면 된다.
org.springframework.http > HttpStatus
(참고)Header의 Content type : key-value 형태로 Response 본문의 형식을 알려준다.
(1) 없음
(2) Response 본문 내용이 HTML - Content type: text/html
(3) Response 본문 내용이 JSON - Content type: application/json
@ExceptionHandler({ IllegalArgumentException.class }) // Exception 할 클래스 명시
public ResponseEntity handleException(IllegalArgumentException ex) {
RestApiException restApiException = new RestApiException();
restApiException.setHttpStatus(HttpStatus.BAD_REQUEST);
restApiException.setErrorMessage(ex.getMessage());
return new ResponseEntity(
// HTTP body
restApiException,
// HTTP status code
HttpStatus.BAD_REQUEST
);
}
위의 코드를 Controller에 넣으면 그 컨트롤러의 모든 함수에 예외처리를 적용한다(AOP 활용)
위와 같이 컨트롤러마다 ExeptionHandler를 다는 것은 비효율적.
@ControllerAdvice를 통해 모든 컨트롤러의 예외처리를 통합해서 할 수 있다.
(@RestControllerAdvice = @ControllerAdvice + @ResponseBody)
@RestControllerAdvice
public class RestApiExceptionHandler {
@ExceptionHandler(value = { IllegalArgumentException.class })
public ResponseEntity<Object> handleApiRequestException(IllegalArgumentException ex) {
RestApiException restApiException = new RestApiException();
restApiException.setHttpStatus(HttpStatus.BAD_REQUEST);
restApiException.setErrorMessage(ex.getMessage());
return new ResponseEntity(
restApiException,
HttpStatus.BAD_REQUEST
);
}
}
public enum ErrorCode {
// 400 Bad Request
DUPLICATED_FOLDER_NAME(HttpStatus.BAD_REQUEST, "400_1", "중복폴더명이 이미 존재합니다."),
BELOW_MIN_MY_PRICE(HttpStatus.BAD_REQUEST, "400_2", "최저 희망가는 최소 " + MIN_MY_PRICE + " 원 이상으로 설정해 주세요."),
// 404 Not Found
NOT_FOUND_PRODUCT(HttpStatus.NOT_FOUND, "404_1", "해당 관심상품 아이디가 존재하지 않습니다."),
NOT_FOUND_FOLDER(HttpStatus.NOT_FOUND, "404_2", "해당 폴더 아이디가 존재하지 않습니다."),
;
private final HttpStatus httpStatus;
private final String errorCode;
private final String errorMessage;
ErrorCode(HttpStatus httpStatus, String errorCode, String errorMessage) {
this.httpStatus = httpStatus;
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
}