@ControllerAdvice
로 모든 컨트롤러에서 발생할 예외를 정의
@ExceptionHandler
를 통해 발생하는 예외마다 처리할 메소드를 정의
@ControllerAdvice
@Controller
나 @RestController
에서 발생한 예외를 한 곳에서 관리하고 처리할 수 있게 도와주는 어노테이션try-catch
를 통한 예외 처리는 코드라인도 길어지고 가독성이 떨어짐@RestControllerAdvice
를 사용하면 됨@ExceptionHandler
@ExceptionHandler(00Exception.class)
@RestController
에서 호출@RestControllerAdvice
에서 호출한 것보다 우선순위가 높음@RestController
public class ExceptionController {
private final Logger LOGGER = LoggerFactory.getLogger(ExceptionController.class);
@ExceptionHandler(value = Exception.class)
public ResponseEntity<Map<String, String>> ExceptionHandler(Exception e) {
HttpHeaders responseHeaders = new HttpHeaders();
// responseHeaders.add(HttpHeaders.CONTENT_TYPE, "application/json");
HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
LOGGER.info(e.getMessage());
LOGGER.info("Controller 내 ExceptionHandler 호출");
Map<String, String> map = new HashMap<>();
map.put("error type", httpStatus.getReasonPhrase());
map.put("code", "400");
map.put("message", "에러 발생");
return new ResponseEntity<>(map, responseHeaders, httpStatus);
}
}
@RestControllerAdvice
에서 호출@RestController
에서 호출한 것보다 우선순위가 낮음@RestControllerAdvice
public class AroundHubExceptionHandler {
private final Logger LOGGER = LoggerFactory.getLogger(AroundHubExceptionHandler.class);
@ExceptionHandler(value = Exception.class)
public ResponseEntity<Map<String, String>> ExceptionHandler(Exception e) {
HttpHeaders responseHeaders = new HttpHeaders();
// responseHeaders.add(HttpHeaders.CONTENT_TYPE, "application/json");
HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
LOGGER.error("Advice 내 ExceptionHandler 호출, 원인: {}, 메시지: {}", e.getCause(), e.getMessage());
Map<String, String> map = new HashMap<>();
map.put("error type", httpStatus.getReasonPhrase());
map.put("code", "400");
map.put("message", "에러 발생");
return new ResponseEntity<>(map, responseHeaders, httpStatus);
}
}
ExceptionController.class
)@RestController
public class ExceptionController {
@PostMapping("/exception")
public void exceptionTest() throws Exception {
throw new Exception();
}
}
@RestController
에서 호출한 것이 RestControllerAdvice
에서 호출한 것보다 우선순위가 높음 -> Controller 내 ExceptionHandler 호출
로그 출력AroundHubExceptionHandler.java
@ExceptionHandler(value = Exception.class)
: Exception.class
에러가 발생하면 JSON 형식으로 발생한 예외를 정의함@ExceptionHandler(value = AroundHubException.class)
: 다양한 예외 사례들을 오버라이딩으로 나열하여 처리@RestControllerAdvice
public class AroundHubExceptionHandler {
private final Logger LOGGER = LoggerFactory.getLogger(AroundHubExceptionHandler.class);
@ExceptionHandler(value = Exception.class)
public ResponseEntity<Map<String, String>> ExceptionHandler(Exception e) {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.add(HttpHeaders.CONTENT_TYPE, "application/json");
HttpStatus httpStatus = HttpStatus.BAD_REQUEST;
LOGGER.error("ExceptionHandler 호출, 원인: {}, 메시지: {}", e.getCause(), e.getMessage());
Map<String, String> map = new HashMap<>();
map.put("error type", httpStatus.getReasonPhrase());
map.put("code", "400");
map.put("message", "에러 발생");
return new ResponseEntity<>(map, responseHeaders, httpStatus);
}
// ExceptionHandler 오버라이딩
@ExceptionHandler(value = AroundHubException.class)
public ResponseEntity<Map<String, String>> ExceptionHandler(AroundHubException e) {
HttpHeaders responseHeaders = new HttpHeaders();
LOGGER.error("AroundHubException 호출, 원인: {}, 메시지: {}", e.getCause(), e.getMessage());
Map<String, String> map = new HashMap<>();
map.put("error type", e.getHttpStatusType());
map.put("error code", Integer.toString(e.getHttpStatusCode()));
map.put("message", e.getMessage());
return new ResponseEntity<>(map, responseHeaders, e.getHttpStatus());
}
}
AroundHubException.java
public class AroundHubException extends Exception {
private static final long serialVersionUID = 4663380430591151694L;
private ExceptionClass exceptionClass;
private HttpStatus httpStatus;
public AroundHubException(ExceptionClass exceptionClass, HttpStatus httpStatus, String message) {
super(exceptionClass.toString() + message);
this.exceptionClass = exceptionClass;
this.httpStatus = httpStatus;
}
public int getHttpStatusCode() {
return httpStatus.value();
}
public String getHttpStatusType() {
return httpStatus.getReasonPhrase();
}
public HttpStatus getHttpStatus() {
return httpStatus;
}
}
Constants.java
, enum ExceptionClass
public class Constants {
public enum ExceptionClass {
MEMBER("Member"), DRAWING("Drawing"), HEART("Heart"), SCRAP("Scrap"), NFT("Nft");
private String exceptionClass;
ExceptionClass(String exceptionClass) {
this.exceptionClass = exceptionClass;
}
public String getExceptionClass() {
return exceptionClass;
}
@Override
public String toString() {
return getExceptionClass() + " Exception. ";
}
}
}
ExceptionController.class
)@RestController
public class ExceptionController {
@PostMapping(value = "/member/exception")
public void exceptionTest2() throws AroundHubException {
throw new AroundHubException(Constants.ExceptionClass.MEMBER, HttpStatus.FORBIDDEN, "접근이 금지되었습니다.");
}
}
AroundHubException.java
와 관련된 에러 로그 출력