쌓고 쌓다
HTTP 요청 메시지 바디에 TEXT, JSON 받기 (@RequestBody) 본문
요청 파라미터를 처리하는 @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 응답
'프로그래밍 > spring' 카테고리의 다른 글
[스프링 부트] 다중(멀티) 게시판으로 변경 - 23 (0) | 2023.08.14 |
---|---|
HTTP 메시지 컨버터? (0) | 2023.08.13 |
@ModelAttribute ? (0) | 2023.08.12 |
[스프링 부트] 게시글 수정시 첨부파일 수정 방법 - 22 (0) | 2023.08.11 |
@RequestParam + required / defaultValue / Map (0) | 2023.08.10 |