minOS

스프링 MVC 기본 기능 - HTTP 요청 메시지(2) 본문

TIL/김영한의 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

스프링 MVC 기본 기능 - HTTP 요청 메시지(2)

minOE 2024. 7. 30. 23:09
728x90

HTTP 요청 메시지 - JSON

이번에는 HTTP API에서 주로 사용하는 JSON 데이터 형식을 조회해보자.
기존 서블릿에서 사용했던 방식과 비슷하게 시작해보자.
/**
 * 이 컨트롤러는 JSON 형식의 요청 본문을 처리하는 다양한 방법을 보여줍니다.
 * 예시 요청 본문: {"username":"hello", "age":20}
 * Content-Type: application/json
 */​

1)HttpServletRequest와 HttpServletResponse를 사용하여 JSON 요청 본문을 읽고 처리하는 방법
    @PostMapping("/request-body-json-v1")
    public void requestBodyJsonV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 요청 본문을 읽기 위한 InputStream
        ServletInputStream inputStream = request.getInputStream();
        // InputStream을 String으로 변환
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

        // 요청 본문을 로그에 출력
        log.info("messageBody = {}", messageBody);

        // JSON 문자열을 HelloData 객체로 변환
        HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);

        // HelloData 객체의 필드를 로그에 출력
        log.info("username =  {} , age = {}", helloData.getUsername(), helloData.getAge());

        // 응답 본문에 "ok" 작성
        response.getWriter().write("ok");
    }


Postman


2) @RequestBody를 사용하여 JSON 요청 본문을 String으로 직접 받아 처리하는 방법

 @ResponseBody
    @PostMapping("/request-body-json-v2")
    public String requestBodyJsonV2(@RequestBody String messageBody) throws IOException {
        // 요청 본문을 로그에 출력
        log.info("messageBody = {}", messageBody);

        // JSON 문자열을 HelloData 객체로 변환
        HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);

        // HelloData 객체의 필드를 로그에 출력
        log.info("username =  {} , age = {}", helloData.getUsername(), helloData.getAge());

        // 응답 본문에 "ok" 반환
        return "ok";
    }


Postman



3) @RequestBody를 사용하여 JSON 요청 본문을 HelloData 객체로 직접 받아 처리하는 방법

@RequestBody 객체 파라미터
- @RequestBody HelloData data
- @RequestBody에 직접 만든 객체를 지정할 수 있다.

 @ResponseBody
    @PostMapping("/request-body-json-v3")
    public String requestBodyJsonV3(@RequestBody HelloData helloData) {
        // HelloData 객체의 필드를 로그에 출력
        log.info("username =  {} , age = {}", helloData.getUsername(), helloData.getAge());

        // 응답 본문에 "ok" 반환
        return "ok";
    }

 

HttpEntity` , `@RequestBody` 를 사용하면 HTTP 메시지 컨버터가 HTTP 메시지 바디의 내용을 우리가 원하는 문자나 객체 등으로 변환해준다.

HTTP 메시지 컨버터는 문자 뿐만 아니라 JSON도 객체로 변환해주는데,  방금 V2에서 했던 작업을 대신 처리 해준다.

 


Postman


 @RequestBody는 생략 불가능

    @ResponseBody
    @PostMapping("/request-body-json-v3")
    public String requestBodyJsonV3(HelloData helloData) {
        // HelloData 객체의 필드를 로그에 출력
        log.info("username =  {} , age = {}", helloData.getUsername(), helloData.getAge());

        // 응답 본문에 "ok" 반환
        return "ok";
    }

생략한 경우


생략한 경우 위의 코드는 아래와 같다.

@ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV3(@ModelAttribute HelloData helloData) {
    // HelloData 객체의 필드를 로그에 출력
    log.info("username =  {} , age = {}", helloData.getUsername(), helloData.getAge());

    // 응답 본문에 "ok" 반환
    return "ok";
}

HelloData`@RequestBody` 를 생략하면 `@ModelAttribute` 가 적용되어버린다.

따라서 생략하면 HTTP 메시지 바디가 아니라 요청 파라미터를 처리하게 된다.


4)HttpEntity를 사용하여 JSON 요청 본문을 HelloData 객체로 직접 받아 처리하는 방법

 @ResponseBody
    @PostMapping("/request-body-json-v4")
    public String requestBodyJsonV4(HttpEntity<HelloData> httpEntity) {
        // HttpEntity에서 본문을 추출하여 HelloData 객체로 변환
        HelloData data = httpEntity.getBody();

        // HelloData 객체의 필드를 로그에 출력
        log.info("username =  {} , age = {}", data.getUsername(), data.getAge());

        // 응답 본문에 "ok" 반환
        return "ok";
    }

Postman


5) @RequestBody를 사용하여 JSON 요청 본문을 HelloData 객체로 직접 받아 처리하고, 이를 그대로 응답 본문으로 반환하는 방법

    @ResponseBody
    @PostMapping("/request-body-json-v5")
    public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
        // HelloData 객체의 필드를 로그에 출력
        log.info("username =  {} , age = {}", data.getUsername(), data.getAge());

        // HelloData 객체를 응답 본문으로 반환
        return data;
    }



@ResponseBody`

응답의 경우에도 `@ResponseBody` 를 사용하면 해당 객체를 HTTP 메시지 바디에 직접 넣어줄 수 있다. 물론 이 경우에도 `HttpEntity` 를 사용해도 된다.

 

728x90