ResponseEntity ๋Œ€์‹  Custom DTO ๋ฅผ ๋ฆฌํ„ดํ•  ๋•Œ ์ฃผ์˜ํ•  ์  (feat. @ResponseBody)

2021. 12. 22. 14:49ใ†Backend/๐ŸŒฟ Spring

[ ๊ธฐ์กด ์˜ˆ์™ธ์ฒ˜๋ฆฌ ํ•ธ๋“ค๋Ÿฌ ์ฝ”๋“œ ]

๋ฆฌํ„ด ํƒ€์ž…์ด ResponseEntity ์ธ ํด๋ž˜์Šค๋‹ค. ๋ฌธ์ œ์—†์ด ์—๋Ÿฌ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๊ณ  ์žˆ์—ˆ๋Š”๋ฐ,

๋ฆฌํ„ด ํƒ€์ž…์„ KlagoExceptionDTO ๋กœ ๋ฐ”๊พธ์–ด ๋ณด๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค. (KlagoExceptionDTO ๋Š” ์ปค์Šคํ…€ ์˜ˆ์™ธ์ฒ˜๋ฆฌ DTO ์ž…๋‹ˆ๋‹ค.)

 

์ด์œ ๋Š” ResponseEntity์˜ ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ๋งค๋ฒˆ httpStatus ์ฝ”๋“œ๋ฅผ ์‚ฝ์ž…ํ•ด์•ผํ–ˆ๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ,

@ResponseStatus() ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋ฉด ์กฐ๊ธˆ๋” ์ง๊ด€์ ์ธ ์ฝ”๋“œ๊ฐ€ ๋  ๊ฒƒ์ด๋ผ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. 

( * ์‚ฌ์‹ค httpStatus ๋ฅผ ๋„˜๊ธฐ๋Š” ๊ฒƒ๊ณผ @ResponseStatus() ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋Š” ๊ฒƒ์˜ ์ฐจ์ด๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค. ) 

@ControllerAdvice
public class KlagoExceptionAdvice {

    @ExceptionHandler(KlagoCustomException.class)
    public ResponseEntity<?> invalidParamException(KlagoCustomException e) {
        HttpStatus httpStatus = HttpStatus.BAD_REQUEST;

        KlagoExceptionDTO klagoExceptionDTO = new KlagoExceptionDTO(
                e.getCode(),
                e.getMessage(),
                e
        );
        return new ResponseEntity<>(klagoExceptionDTO, httpStatus);
    }
}
 

 

[ ๋ฆฌํ„ด ํƒ€์ž… ๋ณ€๊ฒฝํ•œ ์ฝ”๋“œ ]

์•„๋ž˜์ฒ˜๋Ÿผ ์ˆ˜์ •ํ•˜์˜€๋Š”๋ฐ javax.servlet.ServletException ์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

@ControllerAdvice
public class KlagoExceptionAdvice {

    @ExceptionHandler(KlagoCustomException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public KlagoExceptionDTO invalidParamException(KlagoCustomException e) {

        KlagoExceptionDTO klagoExceptionDTO = new KlagoExceptionDTO(
                e.getCode(),
                e.getMessage(),
                e
        );
        return klagoExceptionDTO;
    }
}

[err] javax.servlet.ServletException: Circular view path [selectTest]: would dispatch back to the current handler URL ...

 

 

์—๋Ÿฌ ๋ฐœ์ƒ์˜ ์›์ธ์€ @ResponseBody ์˜ ๋ถ€์žฌ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 

์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ๋กœ ์‘๋‹ต์„ ๋ณด๋‚ผ ๋•, ๋ณธ๋ฌธ์— ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์•„์„œ ๋ณด๋‚ด์•ผํ•˜๋Š”๋ฐ ์ด ๋ณธ๋ฌธ์ด ๋ฐ”๋กœ HTTP ์˜ body ์— ํ•ด๋‹น๋ฉ๋‹ˆ๋‹ค.

์ฆ‰ ์š”์ฒญ๋ณธ๋ฌธ์€ requestBody, ์‘๋‹ต๋ณธ๋ฌธ์€ responseBody ์— ๋‹ด์•„์„œ ๋ณด๋‚ด์•ผํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด ์ˆ˜์ • ์ „ ์ฝ”๋“œ์ธ ResponseEntity<> ํƒ€์ž…์„ ๋ฆฌํ„ดํ•  ๋• ServletException ์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜๋˜ ์ด์œ ๋ฅผ ์ถ”๋ก  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ์„  ResponseEntity ๋‚ด๋ถ€๋ฅผ ๊นŒ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฒซ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์— body ๋ผ๊ณ  ๋ช…์‹œ๋ผ ์žˆ๋Š”๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ฆ‰ ResponseEntity ํƒ€์ž…์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š”๊ฑด ์ž๋™์œผ๋กœ HTTP ์˜ body ๋ฅผ ํฌํ•จํ•œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌํ•˜์—ฌ ๋ฌธ์ œ์—†์ด ResponseBody ์— ๋ฐ์ดํ„ฐ(KlagoExceptionDTO, httpStatus) ๋ฅผ ๋‹ด์•„ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 

 

 

[ ํ•ด๊ฒฐ๋ฐฉ๋ฒ• ]

๊ทธ๋ ‡๋‹ค๋ฉด ResponseEntity ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ต์„ ๋ณด๋‚ด๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ์š” ?

ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์‘๋‹ต์„ ๋ณด๋‚ด๋Š” Controller ๋ฅผ ์ƒ๊ฐํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋”ฑํžˆ ResponseEntity ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ ์‘๋‹ต์„ ์ž˜ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ด์œ ๋Š” ๋ฐ”๋กœ @ResponseBody  ์–ด๋…ธํ…Œ์ด์…˜ ๋•๋ถ„์ธ๋ฐ์š”, ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ HTTP ์‘๋‹ต ๋ณธ๋ฌธ์˜ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ๋กœ ์ „์†กํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋ ‡๊ธฐ์— @ResponseBody ์–ด๋…ธํ…Œ์ด์…˜์„ KlagoExceptionAdvice ํด๋ž˜์Šค์— ๋ถ™์—ฌ์ฃผ๋ฉด, klagoExceptionDTO ๋ผ๋Š” ์ž๋ฐ” ๊ฐ์ฒด๋ฅผ HTTP Body ์— ๋‹ด์•„ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@ControllerAdvice
@ResponseBody // <- ์ถ”๊ฐ€๋œ ๋ถ€๋ถ„
public class KlagoExceptionAdvice {

    @ExceptionHandler(KlagoCustomException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public KlagoExceptionDTO invalidParamException(KlagoCustomException e) {

        KlagoExceptionDTO klagoExceptionDTO = new KlagoExceptionDTO(
                e.getCode(),
                e.getMessage(),
                e
        );
        return klagoExceptionDTO;
    }
}

 

 

+ ์กฐ๊ธˆ ๋” ์ˆ˜์ •์„ ํ•˜์ž๋ฉด, @ControllerAdvice ๋ฅผ @RestControllerAdvice ๋กœ ๋ฐ”๊ฟ”์ฃผ๋ฉด @ResponseBody ์˜ ์—ญํ• ๊นŒ์ง€ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜์ž๋ฉด, @RestControllerAdvice = @ControllerAdvice + @ResponseBody ๋กœ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

@RestControllerAdvice  // <- @ControllerAdvice + @ResponseBody
public class KlagoExceptionAdvice {

    @ExceptionHandler(KlagoCustomException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public KlagoExceptionDTO invalidParamException(KlagoCustomException e) {

        KlagoExceptionDTO klagoExceptionDTO = new KlagoExceptionDTO(
                e.getCode(),
                e.getMessage(),
                e
        );
        return klagoExceptionDTO;
    }
}
 

 

 

[ ๊ฒฐ๊ณผ ]

๊ทธ๋ฆฌํ•˜์—ฌ ResponseEntity<> ๋Œ€์‹  KlagoExceptionDTO ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ฆฌํ„ดํ•  ์ˆ˜ ์žˆ๊ณ , 

@ResponseStatus() ์–ด๋…ธํ…Œ์ด์…˜๋„ ์‚ฌ์šฉํ•˜์—ฌ ์ง€์ •ํ•œ ์ƒํƒœ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋์Šต๋‹ˆ๋‹ค.