오늘은 Rest API를 만들면서 공통적인 Response 처리를 하고 싶어서 별도의 Code 객체를 만들 생각이다.
Rest API를 만들면서 각종 라이브러리를 사용하게 된다. 라이브러리를 사용하면서 어떠한 예외나 에러가 발생하게되면, 프론트엔드와 합의되지않은 Response가 반환되게 된다.
프론트엔드 또한, 합의된 Response를 바탕으로 구현되게끔 되어있어서 당황하겠지..
그리하여 공통적인 Code를 합의하고 해당 코드를 관리하도록 하려고 한다.
Code는 enum으로 처리를 하려고 한다.
@Getter
@AllArgsConstructor
public enum Code {
INDEX_NOT_FOUND(1001, "인덱스가 존재하지 않습니다."),
BOARD_NOT_FOUND(1002, "게시글을 찾을 수 없습니다."),
UNKNOWN_ERROR(1003, "토큰이 존재하지 않습니다."),
WRONG_TYPE_TOKEN(1004, "변조된 토큰입니다."),
EXPIRED_TOKEN(1005, "만료된 토큰입니다."),
UNSUPPORTED_TOKEN(1006, "변조된 토큰입니다."),
ACCESS_DENIED(1007, "권한이 없습니다.");
private int code;
private String message;
}
저기에서 보이는 값들(1001 ~ 1007)은 프론트엔드와 합의하고 적어넣어야 한다. 실무에서는 해당 값들이 문서로 산정되어있을 것이라고 예상이 된다.
일단 객체는 생성했다.
먼저 스프링 시큐리티의 Endpoint에서 적용해보겠다!
@Slf4j
@Component
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
String exception = request.getAttribute("exception").toString();
if(exception == null) {
setResponse(response, Code.UNKNOWN_ERROR);
}
//잘못된 타입의 토큰인 경우
else if(exception.equals(Code.WRONG_TYPE_TOKEN.getCode()+"")) {
setResponse(response, Code.WRONG_TYPE_TOKEN);
}
//토큰 만료된 경우
else if(exception.equals(Code.EXPIRED_TOKEN.getCode()+"")) {
setResponse(response, Code.EXPIRED_TOKEN);
}
//지원되지 않는 토큰인 경우
else if(exception.equals(Code.UNSUPPORTED_TOKEN.getCode()+"")) {
setResponse(response, Code.UNSUPPORTED_TOKEN);
}
else {
setResponse(response, Code.ACCESS_DENIED);
}
}
//한글 출력을 위해 getWriter() 사용
private void setResponse(HttpServletResponse response, Code code) throws IOException {
response.setContentType("application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
JSONObject responseJson = new JSONObject();
responseJson.put("message", code.getMessage());
responseJson.put("code", code.getCode());
response.getWriter().print(responseJson);
}
}
분기되는 상황에 따라 코드를 받아와서 "setResponse" 메소드를 통해서 json으로 변환해주는 것을 볼 수 있다.
package com.togethersports.tosproejct.exception;
@Slf4j
@RestControllerAdvice
public class ErrorControllerAdvice {
@ExceptionHandler(value = UsernameNotFoundException.class)
protected ResponseEntity<ErrorResponse> handleUserNameNotFoundException(){
ErrorResponse response = new ErrorResponse(Code.BOARD_NOT_FOUND);
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}
}
다음으로는 ErrorResponse에서 Code객체를 처리하도록 만들어야 한다.
@ToString
@Getter
public class ErrorResponse {
// HttpStatus
private int status;
// Http Default Message
private String message;
public ErrorResponse(Code code){
this.status = code.getCode();
this.message = code.getMessage();
}
}
이렇게하면 ResponseEntity를 사용할 수 있게 된다!
계속 진행하면서 추가하겠다!