쌓고 쌓다

HTTP 요청 메시지 바디에 TEXT, JSON 받기 (@RequestBody) 본문

프로그래밍/spring

HTTP 요청 메시지 바디에 TEXT, JSON 받기 (@RequestBody)

승민아 2023. 8. 12. 13:06

요청 파라미터를 처리하는 @RequestParam, @ModelAttribute와 다르게

HTTP 메시지 바디에 직접 데이터가 담겨오는경우 어떻게 처리해야할까?

이떄는 요청 파라미터 방식인 @RequestParam, @ModelAttribute로 처리할 수 없다.

(HTML Form 형식으로 오는것은 요청 파라미터로 처리한다.)

 

단순 텍스트 받기

차근차근 스프링을 사용해보자.

 

먼저 서블릿을 사용하여 처리해보자.

@PostMapping("/request-body-string-v1")
public void requestBodyString(HttpServletRequest request, HttpServletResponse response) throws IOException {
    ServletInputStream inputStream = request.getInputStream();
    String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
    // 스트림은 바이트코드라 바이트코드를 문자로 받을때 인코딩을 지정해줘야함.
    
    response.getWriter().write("ok");
}

InputStream을 통해 HTTP 메시지 바디의 데이터를 읽을 수 있다.

간단히 InputStream를 얻어 이 스트림을 통해 바이트를 읽어 문자로 변환하는 과정을 거쳤다고만 이해하자.

 

자바 InputStream에 대해 이해하기 쉬운 블로그 글이다.

https://lannstark.tistory.com/34

 

+ InputStream(Reader): HTTP 요청 메시지 바디의 내용을 직접 조회

   OutputStream(Writer): HTTP 응답 메시지의 바디에 직접 결과 출력

 

 

이번에는 파라미터로 바로 InputStream과 Writer를 받아보자.

V2 - InputStream, Writer

@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는 위의 파라미터를 지원한다.

 

V3 - HttpEntity

@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) throws IOException {
    String messageBody = httpEntity.getBody();
    return new HttpEntity<>("ok");
    // 요청 파라미터는 GET에 쿼리 파라미터가 오는거 또는 POST에 form 데이터 전송하는경우에만 @RequestParam, @ModelAttribute를 쓰는것임.
}

스프링이 지원하는 HttpEntity이다. 파라미터로도 지원하기에 사용할 수 있다.

HttpEntity<String>에서 body의 내용을 String으로 바꿔 넣어준다.

HttpEntity로 HTTP 헤더와 바디를 쉽게 조회할 수 있으며 요청과 응답에 모두 사용할 수 있다.

메시지 바디를 직접 조회하고 반환하는데 HttpMessageConverter가 사용된다.

메시지 컨버터에 대한 것은 나중에 학습하자...

 

V4 - ResponseEntity

@PostMapping("/request-body-string-v4")
public ResponseEntity<String> requestBodyStringV4(RequestEntity<String> httpEntity) throws IOException {
    String messageBody = httpEntity.getBody();
    return new ResponseEntity<>("ok", HttpStatus.CREATED);
}

ResponseEntity도 HttpEntity를 상속 받은 클래스이다.

  • RequestEntity : HttpMethod, url 정보가 추가되었으며 요청에 사용한다.
  • ResponseEntity : HTTP 상태 코드 설정이 가능하며 응답에 사용한다.
    • 위의 ResponseEntity는 Body에 "ok", 상태코드 CREATED를 넣은 것이다.

 

V5 - @RequestBody

@ResponseBody
@PostMapping("/request-body-string-v5")
public String requestBodyStringV4(@RequestBody String messageBody) throws IOException {
    log.info("messageBody = {}", messageBody);
    return "ok"; // @ResponseBody가 있기에 응답 바디에 "ok" 팍 넣어서 반환한다.
}

@RequestBody로 HTTP 메시지 바디 정보를 편하게 조회할 수 있다. ( 헤더는 @RequestHeader )

@ResponseBody는 응답 결과 Body에 직접 담는것이다.

 

@RequestBody 정리

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

 

JSON 받기

데이터는 JSON으로 요청을 보낼것이다.

{"username":"hello", "age":20}
content-type: application/json

 

이제 바디에 담긴 데이터를 @RequestBody로 손쉽게 받을 수 있다는걸 알았다.

JSON으로 들어오는 요청 데이터를 어떻게 조회할까?

@ResponseBody
@PostMapping("/request-body-json-v3")
public String requestBodyJsonV3(@RequestBody HelloData helloData){
    log.info("username={}, age={}",helloData.getUsername(), helloData.getAge());
    return "ok";
}

@RequestBody 객체 파라미터를 넣으면

한번에 객체로 변환이 가능하다.

 

@RequestBody도 생략이 가능할까?

어노테이션이 생략된 경우

단순 타입은 @RequestParam이 적용되고 나머지는 @ModelAttribute가 적용되었었다.

@RuquestBody 생략시 @ModelAttribute가 적용되고 쿼라 파라미터가 없어 값이 들어가지 않는다.

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

 

+ JSON 응답

@ResponseBody
@PostMapping("/request-body-json-v5")
public HelloData requestBodyJsonV5(@RequestBody HelloData data){
    return data; // HelloData 객체가 http메시지 컨버터를 통해 JSON으로 바뀌고 이 JSON이 응답으로 나간다.
}

객체를 @ResponseBody로 바디에 직접 넣어 반환하면 응답으로 JSON이 나간다.

 

JSON 요청 및 응답 정리

  • @RequestBody 요청
    • JSON 요청 -> HTTP 메시지 컨버터를 통해 -> 객체
  • @ResponseBody 응답
    • 객체 -> HTTP 메시지 컨버터를 통해 -> JSON 응답
Comments