- @ExceptionHandler를 사용하여 예외 처리를 하고 클라이언트에게 ResponseEntity를 사용하여 보여줄 정보만 보내려고 한다. 이때 ExceptionResponse라는 것을 만들어서 이곳에 커스텀 Exception으로 만든 enum을 넘겨주려고 했다. 이 ExceptionResponse를 다른 곳에서 재사용하고 싶어 enum을 추상화하여 만들게 된 계기다.
- 코드 - https://github.com/delvering17/toy_board
- 로그인 요청을 받는데 정보가 없는 사용자이거나 비밀번호가 맞지 않을 때의 exception을 처리할 ExceptionHandler이다.
@ExceptionHandler(LoginException.class)
public ResponseEntity<ExceptionResponse> loginExHandle(LoginException e, Model model) {
log.error("[loginExHandle] ex", e);
ExceptionResponse exceptionResponse = new ExceptionResponse(e.getLoginExceptionCode());
return ResponseEntity.status(exceptionResponse.getStatus()).body(exceptionResponse);
}
- LoginExceptoin을 커스텀으로 만들었고 이 안에 LoginExceptionCode라는 enum을 넘겨주어서 처리하도록 했다.
@Getter
public class LoginException extends RuntimeException {
private final LoginExceptionCode loginExceptionCode;
public LoginException(LoginExceptionCode loginExceptionCode) {
super(loginExceptionCode.getMessage());
this.loginExceptionCode = loginExceptionCode;
}
}
@Getter
public enum LoginExceptionCode{
LOGIN_NOTFOUND_MEMBER(HttpStatus.UNAUTHORIZED, "LOGIN_001", "존재하지 않는 회원입니다."),
LOGIN_PASSWORD_MISMATCH(HttpStatus.BAD_REQUEST, "LOGIN_002", "비밀번호가 맞지 않습니다.");
private final HttpStatus status;
private final String code;
private final String message;
LoginExceptionCode(HttpStatus status, String code, String message) {
this.status = status;
this.code = code;
this.message = message;
}
}
- 하지만 이것을 ExceptionResponse를 하나씩 만들기는 그렇고 다른 컨트롤러에서도 사용하고 싶었다. 저 파라미터를 각 필드를 직접 넘겨주는 것을 하려니 loginExHandle 메서드에서는 이를 무엇을 사용해서 넘기는지 명확해보이지 않았다.
// ExceptionResponse.class
@Getter
public class ExceptionResponse {
private final HttpStatus status;
private final String code;
private final String message;
public ExceptionResponse(LoginExceptionCode exceptionCode) {
this.status = exceptionCode.getStatus();
this.code = exceptionCode.getCode();
this.message = exceptionCode.getMessage();
}
}
- 그래서 ExceptionResponse로 넘길 enum을 interfacef를 사용하여 추상화하려고한다
- enum은 extends는 불가능하지만 implements는 가능한 것을 이용하려고 한다.
Interface
public interface ExceptionCode {
HttpStatus getStatus();
String getCode();
String getMessage();
}
- enum 안에서 넘겨줘야 할 메서드들을 적어줬다.
Enum
@Getter
public enum LoginExceptionCode implements ExceptionCode {
LOGIN_NOTFOUND_MEMBER(HttpStatus.UNAUTHORIZED, "LOGIN_001", "존재하지 않는 회원입니다."),
LOGIN_PASSWORD_MISMATCH(HttpStatus.BAD_REQUEST, "LOGIN_002", "비밀번호가 맞지 않습니다.");
private final HttpStatus status;
private final String code;
private final String message;
LoginExceptionCode(HttpStatus status, String code, String message) {
this.status = status;
this.code = code;
this.message = message;
}
}
- 만들어준 ExceptionCode를 implements해서 추상화했다. 이후 다른 MemberExceptionCode나 PostExceptionCode를 사용할 때 해당 인터페이스를 받으면 ExceptionResponse 하나로 응답을 넘겨줄 수 있다.
사용
@Getter
public class ExceptionResponse {
private final HttpStatus status;
private final String code;
private final String message;
public ExceptionResponse(ExceptionCode exceptionCode) {
this.status = exceptionCode.getStatus();
this.code = exceptionCode.getCode();
this.message = exceptionCode.getMessage();
}
}
- 이제 파라미터는 ExceptionCode를 사용하여 유연하게 enum을 받을 수 있다.
참고
'Spring > Spring' 카테고리의 다른 글
[JWT] JWT에 대해서 (0) | 2023.01.21 |
---|---|
스프링 BindingResult 에러 메시지 JSON으로 응답하기 (0) | 2023.01.17 |
스프링 Thymeleaf에서 @ExceptionHandler 활용 (0) | 2023.01.17 |
[Spring] spring 버전 (0) | 2022.12.20 |
댓글