Dev JS Blog

Spring Custom Exception, Custom Response 본문

IT

Spring Custom Exception, Custom Response

Dev JS 2023. 4. 2. 16:39
728x90

1. 공통 Response 만들기

@Getter
@Setter
public class CustomResponse<T>{

    private int status;

    private T data;

    private String message; 

    public CustomResponse(T data) {
    	this.status = HttpStatus.OK.value();
        this.data = data;
    }

    public CustomResponse(int status, T data, String message) {
        this.status = status;
        this.data = data;
        this.message = message;
    }
}

Response 공통 포멧이 될 CustomResponse 클래스를 만들어준다.

public enum ResponseCode {

    SUCCESS("success"),
    USER_NOT_FOUND("user not found");

    private String message;

    ResponseCode(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

성공코드와 에러코드 그리고 메세지를 관리할 ResponseCode enum 을 만들어주었다.

@RestControllerAdvice
public class CustomResponseBodyAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response){
        if(body instanceof CustomResponse){
            return body;
        }
        return new CustomResponse<>(HttpStatus.OK.value(), body, ResponseCode.SUCCESS.getMessage());
    }
}

@RestControllerAdvice 어노테이션을 추가해주고 ResponseBodyAdvice interface를 구현 해준다.
supports 는 true 로 수정해주고 beforeBodyWrite 는 메서드 명에서도 알수있듯이
Response 되기전 내가 Custom한 형태로 response 를 하게 해준다.
Body instanceof CustomResponse 를 추가한 이유는 에러가 났을때 body 가 이미 CustomResponse 폼으로 들어오기 때문에
이미 CustomResponse 형태인 값은 그냥 return 해주면 되기 때문이다.
그리고 String data 를 return 할때는 controller 에서 CustomResponse 로 담아서 return을 할 예정이기 때문이다.

return String

@GetMapping("/test")
public CustomResponse test(){
    return new CustomResponse("테스트");
}

Response
{
  "status": 200,
  "data": "테스트",
  "message": null
}

return Dto

@GetMapping("/test")
public TestDto test(){
    return TestDto.builder()
            .id(1)
            .name("test")
            .email("test@test.com")
            .build();
}

Response 
{
  "status": 200,
  "data": {
    "id": 1,
    "name": "test",
    "email": "test@test.com"
  },
  "message": "success"
}

2. Custom Exception 만들기

@Setter
public class CustomException extends RuntimeException{

    private ResponseCode responseCode;

    public CustomException(ResponseCode errorCode) {
        this.responseCode = errorCode;
    }

    @Override
    public String getMessage() {
        return responseCode.getMessage();
    }
}

RuntimeException 을 상속받아 CustomException 을 만들어준다.
ResponseCode 를 받아서 에러값과 메세지를 처리하게한다.

@RestControllerAdvice
public class CustomExceptionHandler{

    @ExceptionHandler(CustomException.class)
    public CustomResponse customResponse(CustomException e){
        return new CustomResponse(HttpStatus.BAD_REQUEST.value(), null, e.getMessage());
    }
}

RestControllerAdvice 어노테이션을 추가해주고
CustomException 에 대한 Custom 을 해준다.

public TestDto test(){
    if( 1 == 1 ){
        throw new CustomException(ResponseCode.USER_NOT_FOUND);
    }
    return TestDto.builder()
            .id(1)
            .name("test")
            .email("test@test.com")
            .build();
}

Response
{
  "status": 400,
  "data": null,
  "message": "user not found"
}

Exception으로 에러와 메세지를 관리할수가 있다.

728x90

'IT' 카테고리의 다른 글

Expo Android App 만들기 - 2 (스플래시 적용)  (0) 2023.06.07
Expo Android App 만들기 -1  (2) 2023.06.07
스프링 시큐리티 - 2 (회원 등록)  (0) 2023.03.06
스프링 H2 DB 사용하기  (0) 2023.03.05
스프링 시큐리티 - 1  (0) 2023.03.02
Comments