예외가 터지면 자동으로 호출되는 메소드, @ExceptionHandler
사용자에게 알려줘야 하는 예외 처리와 개발자끼리 전달하는 예외 처리 중 사용자에게 알려줘야 하는 예외가 더 많기 때문에 스프링에서는 controller 단에 핸들러를 둔다.
@RequestMapping(value = "/rooms/{id}", method = RequestMethod.GET)
public String getRoom(@PathVariable("id") int id) {
return roomService.getRoom(id).getType();
}
@ExceptionHandler(value = RoomNotFoundException.class)
public String catchRoomNotFoundException(RoomNotFoundException e) {
System.out.println(e.getMessage());
return "No Room!!!";
}
public Room getRoom(int id) {
// try {
return roomRepository.getRoom(id);
// } catch (RoomNotFoundException e) {
// System.out.println(e.getMessage());
// return new NullRoom();
// }
}
서로 다른 컨트롤러에서 같은 예외를 같은 방법으로 처리해야 한다면?
→ 다른 컨트롤러끼리는 @ExceptionHandler 공유를 할 수는 있지만 수동으로 수정해줘야 함, @ControllerAdvice를 사용해서 간편하게 공통으로 처리해준다.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler
public String catchRoomNotFoundException(RoomNotFoundException e) {
System.out.println(e.getMessage());
return "No Room!!!";
}
}
[에러] @ControllerAdvice를 사용했을 시에 포스트맨에서 400에러 발생.
[해결] 컨트롤러가 RestController이기 때문에 ControllerAdvice도 RestControllerAdvice로 써줘야 한다. response body의 값이 다르기 때문에 생기는 오류. RestController의 주용도는 Json 형태로 객체 데이터를 반환하는 것이다.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler
public String catchRoomNotFoundException(RoomNotFoundException e) {
System.out.println(e.getMessage());
return "No Room!!!";
}
}
아래로 내려갈수록 중요도가 높다.
프로젝트 환경에서 로그 레벨 지정 가능! → 예를 들어 로그 레벨을 info로 지정
@RestControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler
public String catchRoomNotFoundException(RoomNotFoundException e) {
logger.error("exception class: {}", e.getClass());
return "No Room!!!";
}
}
프로젝트 환경에서 로그 레벨 지정 가능
설정 레벨과 같거나 높은 레벨의 로그들만 찍힌다.
#로그레벨을 어디까지 띄울지
#log level setting
logging.level.root=warn
서버환경에서도 별도로 로그 레벨 지정 가능
slf4j logger 사용을 간편하게 하기 위해 @slf4j 어노테이션을 제공한다.
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler
public String catchRoomNotFoundException(RoomNotFoundException e) {
log.error("exception class: {}", e.getClass());
return "No Room!!!";
}
}