API 성공, 실패, Exception 발생 시에 같은 포맷의 응답 바디를 만들기 위해 설정
CommonResponse
: 응답 바디 포맷이 되는 Class
ResponseCode
: 각종 응답의 코드, 메세지, 응답 status code 를 가지고 있는 Enum
BusinessException
: 프로젝트 내에서 발생하는 Exception 을 포괄적으로 관리하기 위한 Exception Class
CommonResponse
@Getter
@NoArgsConstructor
public class CommonResponse {
private String resultCode;
private String resultMsg;
private Map<String, Object> data;
@Builder
public CommonResponse(String resultCode, String resultMsg, Map<String, Object> data) {
this.resultCode = resultCode;
this.resultMsg = resultMsg;
this.data = data;
}
/**
* 예시) 현재 Locale: en, {@code MessageSourceUtils.getMessage("S0000")} 실행시 "success" 리턴
* @param code 응답하고자 하는 code 값 (다국어처리를 위한 key 값 * resources/messages/message_{locale}.properties 에 정의되어 있어야 함)
* @return CommonResponse 객체 리턴
*/
public static CommonResponse create(String code) {
return CommonResponse.builder()
.resultCode(code)
.resultMsg(MessageSourceUtils.getMessage(code))
.build();
}
/**
* {@code create(String code)} 에서 추가로 data 값을 이용할 때 사용
*/
public static CommonResponse create(String code, Map<String, Object> data) {
return CommonResponse.builder()
.resultCode(code)
.resultMsg(MessageSourceUtils.getMessage(code))
.data(data)
.build();
}
}
Name | Type | Description |
---|---|---|
resultCode | String | 응답 코드 |
create() static 메서드를 통해 객체 생성
CommonResponse commonResponse = CommonResponse.create(ResponseCode.API_STATUS_OK.getCode(), data);
ResponseCode
@Getter
@AllArgsConstructor
public enum ResponseCode {
/** 공통 코드 */
API_STATUS_OK("S0000", 200),
API_BAD_REQUEST("E1001",400),
...
private final String code;
private final int status;
...
public ResponseEntity<CommonResponse> toResponseEntity(Map<String, Object> data) {
return ResponseEntity
.status(this.getStatus())
.body(CommonResponse.create(this.getCode(), data));
}
...
}
Name | Type | Description |
---|---|---|
code | String | 코드 |
백엔드 서버에서 응답하는 모든 응답코드는 ResponseCode Enum 에 정의된 코드로만 응답해야 하기 때문에 ResponseEntity 객체로 변환해주는 메서드 toResponseEntity() 생성
BusinessException
public class BusinessException extends Exception {
private static final long serialVersionUID = 1L;
private final ResponseCode responseCode;
private final Map<String, Object> data;
public BusinessException(ResponseCode code) {
this.responseCode = code;
this.data = null;
}
public BusinessException(ResponseCode responseCode, Map<String, Object> data) {
this.responseCode = responseCode;
this.data = data;
}
public ResponseCode getResponseCode() {
return this.responseCode;
}
public Map<String, Object> getData() {
return this.data;
}
}
Name | Type | Description |
---|---|---|
responseCode | Object(Enum) | 공통 응답을 위한 code 를 가지고 있는 Enum 객체 |
data | Map | 공통 응답에 들어갈 바디 값 |
비즈니스 로직 실행 중 예외를 발생시켜야 할 때 BusinessException 으로 공통화시켜 발생시키기 때문에 Exception 을 제어하는 ControllerAdvice 에서 응답하기 위한 정보인 resultCode 와 data 값이 필요하기 때문에 ResponseCode Enum 과 data 필드 생성
API 실행 중 예시
성공 케이스
TestController
@GetMapping("/user/{userNo}")
public ResponseEntity<CommonResponse> getUser(@PathVariable String userNo) {
Map<String, Object> userInfo = testService.getUserInfo(userNo);
return ResponseCode.API_STATUS_OK.toResponseEntity(userInfo);
}
응답바디
// Http Status Code : 200
{
"resultCode": "S0000",
"resultMsg": "success",
"data": {
"userNo": "E1000",
"firstName": "George",
"lastName": "Bush",
...
}
}
실패 케이스
TestController
@PostMapping("/user")
public ResponseEntity<CommonResponse> registerUser(@RequestBody UserDTO userDto) {
int result = testService.registerUser(userDto);
if (result != 1) {
throw new BusinessException(ResponseCode.API_FAIL_INSERT);
}
return ResponseCode.API_STATUS_OK.toResponseEntity();
}
ExceptionController
@RestControllerAdvice
@Slf4j
public class ExceptionController {
@ExceptionHandler(BusinessException.class)
protected ResponseEntity<CommonResponse> handleBusinessException(BusinessException e) {
log.error("OCCURRED BUSINESS EXCEPTION :: {}", e.getResponseCode().getCode());
ResponseCode responseCode = e.getResponseCode();
if (responseCode == null) {
responseCode = ResponseCode.API_SERVER_ERROR;
}
return responseCode.toResponseEntity(e.getData());
}
@ExceptionHandler(Exception.class)
protected ResponseEntity<CommonResponse> handleException(Exception e) {
log.error("OCCURRED EXCEPTION :: {} - {}", e.getClass().getName(), e.getMessage());
final ResponseCode responseCode = ResponseCode.API_SERVER_ERROR;
return responseCode.toResponseEntity();
}
}
BusinessException 이 발생할 경우 ControllerAdvice 에서 Exception 내의 ResponseCode Enum 과 Object(Map) data 를 꺼내어 ResponseEntity<CommonResponse> 형태로 응답
응답바디
// Http Status Code : 500
{
"resultCode": "E1004",
"resultMsg": "등록 요청 처리 중 오류가 발생했습니다",
"data": null
}