✏️ HTTP 요청 메세지 - 단순 텍스트

박상민·2023년 7월 28일
0

SpringMVC

목록 보기
7/11
post-thumbnail

📌 HTTP 요청 메세지 - 단순 텍스트

HTTP message body에 데이터를 직접 담아서 요청

  • HTTP API에서 주로 사용, JSON, XML, TEXT
  • 형식은 주로 JSON 사용
  • POST, PUT, PATCH

요청 파라미터와 다르게, HTTP 메세지 바디를 통해 데이터가 직접 넘어오는 경우는 @RequestParam, @ModelAttribute를 사용할 수 없다.

먼저 가장 단순한 텍스트 메세지를 HTTP 메세지 바디에 담아서 전송하고, 읽어보면서 점점 단계적으로 발전시켜 보겠다.

✔︎ 1단계 - InputStream

@Slf4j
@Controller
public class RequestBodyStringController {

    @PostMapping("/request-body-string-v1")
    public void requestBodyString(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        //Stream을 바굴 때에는 인코딩 형식을 지정 
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

        log.info("messageBody={}", messageBody);

        response.getWriter().write("ok");
    }
}

InputStream을 사용하는 가장 단순한 방식이다. HttpServlet을 통해 request, response를 받으며 InputStream을 통해 처리한다

✔︎ 2단계 - (Input, Output) Stream

/**
* InputStream(Reader): HTTP 요청 메시지 바디의 내용을 직접 조회 
* OutputStream(Writer): HTTP 응답 메시지의 바디에 직접 결과 출력 
*/
@PostMapping("/request-body-string-v2")
public void requestBodyStringV2(InputStream inputStream, Writer responseWriter) throws IOException {

    String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
    log.info("messageBody={}", messageBody);
    responseWriter.write("ok");
    }

스프링 MVC는 다음 파라미터를 지원한다.

  • InputStream(Reader): HTTP 요청 메시지 바디의 내용을 직접 조회
  • OutputStream(Writer): HTTP 응답 메시지의 바디에 직접 결과 출력

✔︎ 3단계 - HTTPEntity

/**
* HttpEntity: HTTP header, body 정보를 편리하게 조회
* - 메시지 바디 정보를 직접 조회(@RequestParam X, @ModelAttribute X)
* - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용 
*
* 응답에서도 HttpEntity 사용 가능
- 메시지 바디 정보 직접 반환(view 조회X)
- HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
**/
@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
      String messageBody = httpEntity.getBody();
      log.info("messageBody={}", messageBody);
      return new HttpEntity<>("ok");
}

스프링 MVC는 다음 파라미터를 지원한다.

  • HttpEntity: HTTP header, body 정보를 편리하게 조회
    • 메시지 바디 정보를 직접 조회
    • 요청 파라미터를 조회하는 기능과 관계 없음 @RequestParam X, @ModelAttribute X
  • HttpEntity는 응답에도 사용 가능
    • 메시지 바디 정보 직접 반환
    • 헤더 정보 포함 가능
    • view 조회X

HttpEntity 를 상속받은 다음 객체들도 같은 기능을 제공한다.

  • RequestEntity
    • HttpMethod, url 정보가 추가, 요청에서 사용
  • ResponseEntity
    • HTTP 상태 코드 설정 가능, 응답에서 사용
    • return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED)

✔︎ 4단계 - @RequestBody

/**
* @RequestBody
* - 메시지 바디 정보를 직접 조회(@RequestParam X, @ModelAttribute X)
* - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용 
*
* @ResponseBody
* - 메시지 바디 정보 직접 반환(view 조회X)
* - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용 
*/
@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
     log.info("messageBody={}", messageBody);
     return "ok";
    }

@RequestBody
@RequestBody 를 사용하면 HTTP 메시지 바디 정보를 편리하게 조회할 수 있다. 참고로 헤더 정보가 필요하다면 HttpEntity를 사용하거나 @RequestHeader를 사용하면 된다.
이렇게 메시지 바디를 직접 조회하는 기능은 요청 파라미터를 조회하는 @RequestParam , @ModelAttribute 와는 전혀 관계가 없다.

요청 파라미터 vs HTTP 메시지 바디

  • 요청 파라미터를 조회하는 기능: @RequestParam , @ModelAttribute
  • HTTP 메시지 바디를 직접 조회하는 기능: @RequestBody

@ResponseBody
@ResponseBody 를 사용하면 응답 결과를 HTTP 메시지 바디에 직접 담아서 전달할 수 있다. 물론 이 경우에도 view를 사용하지 않는다.

지금까지 1단계 InputStream부터 4단계 @RequestBody까지 살펴보았다. 4가지 방법을 살펴보았지만, 결국 HttpEntity 또는 @RequestBody 중에서 선택하여 사용하면 된다.

📌 HTTP 요청 메세지 - Json

이번에는 HTTP API에 주로 사용하는 Json 데이터 형식을 조회해보자.
Json 또한 InputStream, @RequestBody를 사용하지만 역시나 HttpEntity, @RequestBody 중에서 선택하여 사용하면 된다.
2가지 방식의 예를 보여주겠다.

✔︎ @RequestBody 객체 변환

/**
* @RequestBody 생략 불가능(@ModelAttribute 가 적용되어 버림)
* HttpMessageConverter 사용 
  -> MappingJackson2HttpMessageConverter (content-type: application/json)
*
*/
@ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV3(@RequestBody HelloData data) { 
      log.info("username={}, age={}", data.getUsername(), data.getAge());
      return "ok";
}
  

@RequestBody 객체 파라미터

  • @RequestBody HelloData data
  • @RequestBody 에 직접 만든 객체를 지정할 수 있다.

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

@RequestBody는 생략 불가능
스프링은 @ModelAttribute, @RequestParam과 같은 해당 애노테이션을 생략시 다음과 같은 규칙을 적용한다.

  • String , int , Integer 같은 단순 타입 = @RequestParam
  • 나머지 = @ModelAttribute (argument resolver 로 지정해둔 타입 외)

따라서 이 경우 HelloData에 @RequestBody 를 생략하면 @ModelAttribute 가 적용되어버린다.
HelloData data -> @ModelAttribute HelloData data
따라서 생략하면 HTTP 메시지 바디가 아니라 요청 파라미터를 처리하게 된다.

✔︎ HttpEntity

@ResponseBody
@PostMapping("/request-body-json-v4")
public String requestBodyJsonV4(HttpEntity<HelloData> httpEntity) {
      HelloData data = httpEntity.getBody();
      log.info("username={}, age={}", data.getUsername(), data.getAge());
      return "ok";
}

앞에서 배운 것처럼 HttpEntity 또한 사용해보았다.
@RequestBody, HttpEntity를 사용할 때 주의할 점이 있다.
HTTP request의 Content-Type가 반드시 application/json이어야 한다. 그래야 Json을 처리할 수 있는 HTTP 메세지 컨버터가 실행된다.


출처
김영한님의 Spring MVC 강의

profile
스프링 백엔드를 공부중인 대학생입니다!

0개의 댓글