코코무의 코딩캔버스

[Spring] ResponseEntity의 개념 및 사용법 본문

Spring

[Spring] ResponseEntity의 개념 및 사용법

코코무 2024. 3. 15. 16:44
ResponseEntity의 개념

 

ResponseEntity는 Spring Framework에서 HTTP 응답을 나타내는 클래스입니다.

 

이 클래스가 무엇인지 정확히 알려면 우선 HTTP에 관한 클래스를 알아야 합니다.

*HTTP(HyperText Transfer Protocol): 클라이언트(브라우저)와 서버 사이에서 이루어지는 요청/응답 프로토콜

*프로토콜(Protocol): 컴퓨터나 원거리 통신 장비 사이에서 메시지를 주고 받는 양식과 규칙의 체계

사람이 주고 받는 편지에도 양식이 있듯 컴퓨터가 주고 받는 편지도 마찬가지다. '주는 편지(요청)', '받는 편지(응답)'를 HTTP라 이해하면 좋을 듯.

 

Spring Framework에는 HttpEntity라는 클래스가 존재합니다.

해당 클래스는 HTTP의 요청(request) 또는 응답(response)에 해당하는 HttpHeader와 HttpBody를 포함합니다.

 

이 HttpEntity를 상속 받아 구현하는 클래스가 바로 RequestEntity와 ResponseEntity입니다.

그 중에서도 ResponseEntity는 사용자의 HttpRequest에 대한 응답 데이터인

HttpStatus(상태 코드) / HttpHeader(응답 헤더) / HttpBody(응답 본문)를 포함합니다.

*HttpHeader: 요청/응답사항이 적힘(이메일 제목이라고 생각하면 될까?)

*HttpBody: 그 사항에 대한 내용이 적힘

 

 

 

 

요약하면,

ResponseEntityHttpEntity 클래스를 상속 받아 구현하는 클래스로,
HttpStatus, HttpHeader, HttpBody 데이터를 포함합니다.

 


ResponseEntity의 기능과 사용하는 이유

 

ResponseEntity의 기능은 다음과 같습니다.

 

1. 응답 상태 코드 설정

HTTP 응답의 상태 코드를 지정할 수 있습니다.

예를 들어, 성공적인 요청에 대한 응답은 상태 코드 200으로 설정할 수 있습니다.

return ResponseEntity<>(success, HttpStatus.OK);

 

2. 응답 헤더 설정

HTTP 응답의 헤더를 설정할 수 있습니다.

예를 들어, 캐시 헤더를 설정하거나 커스텀 헤더를 추가할 수 있습니다.

*캐시 헤더(cache header): 데이터나 정보의 사본을 임시로 저장하는 장소인 캐시의 동작을 지정하고 제어하는 데 사용

*커스텀 헤더(custom header): HTTP 요청 또는 응답에 사용자가 정의한 추가적인 헤더

 

3. 응답 본문 설정

HTTP 응답의 본문을 설정할 수 있습니다.

일반적으로 JSON, XML 또는 기타 형식의 데이터를 응답 본문으로 설정합니다.

 

4. 응답 엔티티 생성

ResponseEntity는 HTTP 응답을 나타내는 객체이며, 이를 사용하여 Spring MVC 컨트롤러에서 요청에 대한 응답을 생성합니다.

 

기능은 알겠는데, ResponseEntity를 도대체 왜 사용하는 것일까요?

첫째, HTTP 응답의 상태 코드와 헤더를 명시적으로 제어할 수 있습니다.응답의 성공 또는 실패를 정확히 나타내고 추가적인 헤더를 설정하여 클라이언트에게 더 많은 정보를 제공합니다.

 

둘째, 다양한 형식의 응답을 지원할 수 있습니다.JSON, XML, 텍스트, 바이너리 데이터 등 다양한 형식의 데이터를 반환할 수 있고,이러한 데이터를 감싸고 HTTP 응답으로 반환 가능합니다.

 

셋째, HTTP 응답 본문과 함께 데이터를 반환할 수 있습니다.controller의 메서드가 단순히 데이터를 반환하는 것 이상의 역할을 수행할 수 있게 되는데예로 응답으이 상태 코드와 헤더를 동적으로 설정하거나 에러 처리와 관련된 정보를 함께 반환할 수 있습니다.

 

넷째, Restful API를 개발할 때 클라이언트에게 응답을 전달합니다.

 

다섯째, controller 메서드의 응답을 테스트할 때 MockMvc를 사용하는데 ResponseEntity를 반환하는 컨트롤러 메서드의 동작을 더욱 명확히 테스트합니다.

 


ResponseEntity의 사용법

 

1. 객체 반환

@RestController
public class MyController {

    @GetMapping("/data")
    public ResponseEntity<String> getData() {
        String data = "This is my data";
        return ResponseEntity.ok(data);
    }
}

ResponseEntity.ok( ) 메서드로 HTTP 응답의 상태 코드를 200으로 설정하고,

반환되는 데이터("This is my data")를 응답 본문에 넣습니다.

 

상태 코드 200일 때(서버상 아무런 오류가 없을 때) data가 브라우저에 표시되게 됩니다.

 

2. 상태 코드 및 헤더 설정

@RestController
public class MyController {

    @GetMapping("/data")
    public ResponseEntity<String> getData() {
        String data = "This is my data";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Custom-Header", "Value");
        return new ResponseEntity<>(data, headers, HttpStatus.OK);
    }
}

ResponseEntity 생성자를 사용하여 응답 본문, 헤더, 상태 코드를 모두 설정합니다.

헤더는 HttpHeaders 객체를 사용하고 상태 코드는 HttpStatus 열거형을 사용합니다.

 

3. 예외 처리 및 에러 응답 생성

@RestController
public class MyController {

    @GetMapping("/data")
    public ResponseEntity<String> getData() {
        try {
            // Some logic to get data
            String data = "This is my data";
            return ResponseEntity.ok(data);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error occurred");
        }
    }
}

예외 발생 시 500 Internal Server Error를 반환합니다.

ResponseEntity.status( ) 메서드로 상태 코드를 설정하고 body( ) 메서드를 사용하여 응답 본문을 설정합니다.

 

이외에도 사용하는 방법은 다음과 같습니다.

public ResponseEntity<String> create(@RequestBody ReplyVO vo) {
                                    //전달된 요청(request)의 내용(body)을 이용해 데이터에게 해당 파라미터의 타입(ReplyVO)으로 변환 요구
    log.info("ReplyVO: " + vo);

    int insertCount = service.register(vo); //service 계층의 register를 호출해 insertCount 변수에 넣음

    log.info("Reply INSERT COUNT: " + insertCount);

    //insertCount == 1 -> 글이 등록됨
    //ResponseEntity<>를 이용해 정상적인 데이터임을 문자열로 전달
    return insertCount == 1 ? new ResponseEntity<>("success", HttpStatus.OK)
    : new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}

본문은 삼항 연산자를 사용한 것으로서

insertCount의 값이 1이면 new ResponseEntity<>("success", HttpStatus.OK)를 처리하고

1이 아니면 new ResponseEntity<>(HttpStatus.Internal_Server_Error)를 처리합니다.

 

전자는 ResponseEntity의 생성자를 통해 상태 코드를 설정(.OK)하여 success에 넣었습니다.

이는 insertCount 데이터가 정상적임을 문자열로 전달하기 위함입니다.

 

후자 역시 생성자를 통해 상태 코드를 설정(.Internal_Server_Error)하였습니다.

 

 

다음은 응답 본문과 상태 코드를 설정하여 생성자에 담아 반환하는 메서드입니다.

@GetMapping(value = "/{rno}", produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE })
public ResponseEntity<ReplyVO> get(@PathVariable("rno") Long rno) {
                                    //REST 방식에서는 URL에 최대한 많은 정보를 담으려고 노력함 -> @PathVariable 어노테이션을 이용해 URL 상에 경로의 일부를 파라미터로 사용함
                                    //{ }를 이용해 변수명을 지정하고 @PathVariable을 이용해 지정된 이름의 변수값을 얻음
    log.info("get: " + rno);

    return new ResponseEntity<>(service.get(rno), HttpStatus.OK);
}

 


내용은 계속해서 업데이트할 예정입니다.

포스팅을 적다보니 응답 본문과 응답 헤더에 대한 내용도 자세히 다루는 것이 필요해 보입니다.

용어가 많아 헷갈리지만 안 봐도 기억할 때까지 계속 보면 장기기억 속에 남지 않을까...생각하며 화이팅 해봅시다👊