SOLID 원칙 중 가장 첫번째 단일책임원칙
- 하나의 클래스는 하나의 역할만 수행해야 한다.
- 변경 사유는 하나여야 한다.
클래스가 너무 많은 책임을 가지면 코드가 복잡해지고 수정하기 어려워질뿐더러
하나의 책임을 변경할 때 다른 책임이 변경될 수 있다.
즉 Controller 자신의 본 책임, 요청과 응답을 처리하는 역할만 가지는 게 가장 좋은 구조이다.
가끔 공부를 하다 보면 Controller 내부에 예외처리코드를 넣은 코드를 보게 된다.
물론 작동은 잘 될 것이다, 하지만 Controller가 많아지고 내부 함수 또한 많아진다면
중복코드발생 및 수정할 때도 많은 시간이 걸릴 것이다...
위 두가지 어노테이션을 같은 클래스에서 사용한다면 모든 Controller에서 발생하는 에러를 공통 로직에서 처리가능하다.
@RestControllerAdvice // 전역 Controller 에러 캐치
public class GlobalExceptionHandler {
// MethodArgumentNotValidException에 대한 에러 처리
@ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<ErrorResponse> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
final ErrorResponse response = ErrorResponse.of(CommonErrorCode.INVALID_INPUT_VALUE, e.getBindingResult());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
// BindException에 대한 에러 처리
@ExceptionHandler(BindException.class)
protected ResponseEntity<ErrorResponse> handleBindException(BindException e) {
final ErrorResponse response = ErrorResponse.of(CommonErrorCode.INVALID_INPUT_VALUE, e.getBindingResult());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
// ConstraintViolationException에 대한 에러 처리
@ExceptionHandler(ConstraintViolationException.class)
protected ResponseEntity<ErrorResponse> handleConstraintViolationException(ConstraintViolationException e) {
final ErrorResponse response = ErrorResponse.of(CommonErrorCode.INVALID_INPUT_VALUE, e.getConstraintViolations());
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
// MissingServletRequestParameterException에 대한 에러 처리
@ExceptionHandler(MissingServletRequestParameterException.class)
protected ResponseEntity<ErrorResponse> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
final ErrorResponse response = ErrorResponse.of(CommonErrorCode.MISSING_REQUEST_PARAMS, e);
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
// NullPointerException에 대한 에러 처리
@ExceptionHandler(NullPointerException.class)
protected ResponseEntity<ErrorResponse> handleNullPointerException(NullPointerException e) {
final ErrorResponse response = ErrorResponse.of(CommonErrorCode.NULL_POINT, e.getMessage());
return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
}
// 나머지 에러처리
@ExceptionHandler(Exception.class)
protected ResponseEntity<ErrorResponse> handleException(Exception e) {
final ErrorResponse response = ErrorResponse.of(CommonErrorCode.INTERNAL_SERVER_ERROR, e.getMessage());
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
}
}