5-3 Spring 요청 데이터 2강 ... HTTP Message Body(요청), TEXT
- HTTP Message Body(요청) ... @RequestParam, @ModelAttribute는 GET + Query Parameter와, POST HTML Form Data를 바인딩하는 방법. 이제부터 배울 내용은 HTTP Message Body에 직접적으로 Data가 전달되는 경우 -> Request Body의 Data를 바인딩하는 방법
- REST API에서 주로 사용
- HTTP Method POST, PUT, PATCH에서 주로 사용
- GET은 Request Body가 존재할 수는 있지만 권장하지 않는다
- JSON, XML, TEXT 등을 데이터 형식으로 사용
- HTTP Message 구조는 아래와 같음
- HTTP Request, Response 예시는 아래와 같음
- Start Line, Header, Message Body에 들어간 내용을 보자. Start Line에는 Method(POST), Header에는 Content-Type(application/json), Message Body에는 json이 들어가 있음
- Server에서 Request로 전달받은 Data를 처리하기 위해서 바인딩을 해야 함 (ex. JSON -> Object)
- TEXT ... HTTP Request Body에 Data가 전송되는 경우 HttpMessageConverter를 통해 바인딩 됨. 현대에는 Restful API를 주로 사용하고 있어 대부분의 경우 JSON 형식으로 통신.
- HttpServletRequest -> request.getInputStream();
- I/O 예시
- InputStream(읽기) 파라미터 지원 ... HTTP Request Body Data 직접 조회
- OutputStream(쓰기) 파라미터 지원 ... HTTP Response Body 직접 결과 출력
- HttpEntity 예시 ... HttpMessageConverter 사용 / HttpEntity를 사용하면 HttpMessageConverter를 사용함
- Spring의 HttpMessageConverter 덕분에 간편하게 Request Data에 접근할 수 있음 -> 1. HttpEntity를 사용하면 HttpMessageConverter가 동작해 자동으로 매핑됨 / 2. 요청 뿐만이 아닌 응답까지 HttpEntity 하나만으로 사용 가능해짐. ... HttpEntity가 좋아 보이는데?
Spring 요청 데이터 3강 (HttpEntity / @RequestBody, @ResponseBody)
- HttpEntity ... HttpEntity는 HTTP Header, Body 정보를 편리하게 조회할 수 있도록 만들어 줌.
- HttpEntity 역할
- Http Request Body Message를 직접 조회
- Request 뿐만 아니라 Response도 사용할 수 있도록 만들어줌
- Response Header 또한 사용 가능
- Request Parameter를 조회하는 기능들과는 아무 관계 X
- View 반환 X
- HttpEntity를 상속받은 객체
- RequestEntity<> ... HTTP Request Method, URL 정보가 추가 되어 있음
- ResponseEntity<> ... HTTP Response 상태 코드 설정이 가능
- 예시
- 위 방법을 적용해도 불편함. (Data를 httpEntity에서 꺼내어 사용해야 함)
- Spring은 Http RequestBody Message를 읽어서 String이나 Object로 자동으로 변환해줌. 이때 HttpMessageConverter가 사용됨
- @RequestBody, @ResponseBody ... Spring에서 @RequestBody, @ResponseBody 어노테이션을 사용하면 각각 Request, Response 객체의 Body에 편하게 접근하여 사용할 수 있음.
- 예시
- @RequestBody ... 요청 메시지 Body Data를 쉽게 조회할 수 있음
- @RequestHeader ... 요청 헤더 정보 조회
- @ResponseBody ... 응답 메시지 바디에 값을 쉽게 담아서 전달. View가 아닌 데이터를 반환.
- 요약
- 요청 파라미터, HTML Form Data에 접근하는 경우 -> @RequestParam, @ModelAttribute를 사용
- Http Message Body에 접근하는 경우 -> @RequestBody를 사용 (JSON, XML, TEXT) ... JSON을 많이 사용
Spring 요청 데이터 4강 (JSON, HTTPMessageConverter)
- JSON ... @RestController에서 가장 많이 사용되는 데이터 형식. 현재 대부분의 API는 Request, Response 모두 JSON 형태로 통신. Json 형태로 Data를 전송할 때는 Request Header의 content-type이 꼭 application/json 이어야 함.
- HttpServletRequest 사용
- HttpServletRequest를 사용해 HTTP Message Body 데이터를 Read해 문자로 변환
- 문자로 만들어진 JSON을 Jackson 라이브러리의 objectMapper를 사용해 Object로 변환
- @RequestBody 사용
- @RequestBody를 사용하여 HTTp Request Body의 Data에 접근
- ObjectMapper 가 반복되는데 ... @ModelAttribute처럼 객체로 바로 반환은 안 되나요?
- ObjectMapper 제거
- @RequestBody
- @RequestBody 어노테이션을 사용하면 Object를 Mapping할 수 있음
- HttpEntity<>, @RequestBody를 사용하면 HTTPMessageConverter가 Request Body의 Data를 개발자가 원하는 String이나 Object로 변환해줌.
- JSON to Object의 Mapping 또한 가능. 쉽게 설명해, HTTP Message Converter가 ObjectMapper를 대신 실행함!
- RequestBody는 생략할 수 없다 ... @RequestParam, @ModelAttribute는 생략 가능
- 이렇게 하면 Tutor tutor를 ModelAttribute로 인식함.
- Request Header의 contentType은 꼭 application/json이어야 함! 위 설정 정보를 기반으로 MessageConverter가 실행됨.
- HttpEntity 사용
- HttpEntity를 사용하면 Tutor tutor = httpEntity.getBody();로 받고, tutor.getName(), tutor.getAge()와 같이 값을 꺼내서 사용해야 함.
- ResponseBody
- View를 조회하지 않고 Response Body에 Data를 입력해서 직접 반환함
- 요청 뿐만이 아니라 응답에도 HttpMessageConverter가 동작함
- MappingJackson2HttpMessageConverter 적용
- 응답 객체인 Tutor가 JSON으로 변환되어 반환됨
- HttpEntity를 사용해도 됨
- 요약
- 요청 데이터는 @RequestBody를 사용해서 바인딩
- @RequestBody는 생략이 불가 (@ModelAttribute가 적용되기 때문)
- HttpMessageConverter가 요청 응답 데이터를 모두 변환할 수 있음
- JSON은 MappingJackson2HttpMessageConverter를 사용
- Request Header의 Content-Type은 application/json이어야 함. Header로 어떤 Converter가 동작할지 판별함
- HTTPMessageConverter ... Spring Framework에서 HTTP 요청과 응답을 변환하는 인터페이스. 클라이언트와 서버 간에 데이트를 주고받을 때, 요청 데이터를 자바 객체로 변환하거나 자바 객체를 응답 본문으로 변환하는 역할을 수행
- MappingJackson2HttpMessageConverter는 JSON을 처리하는 대표적인 HTTPMessageConverter의 구현체
- 역할은 데이터를 Object로 변환. 대표적으로 JSON을 변환함.
- @RequestBody ... 요청 데이터 + Request Header를 참고해 Object로 변환
- HTTP Request Body(JSON Data) -> Converter(Jackson) -> Object
- Request Header -> Content-Type:application/json(전달할 데이터 형식)
- @ResponseBody ... 응답 데이터 + Accept Header를 참고하여 원하는 데이터 형식으로 변환
- Object -> Converter(Jackson) -> HTTP Response Body(JSON Data)
Spring 응답 데이터 1강 (Server에서 Client로 Data를 전달하는 방법 / 정적 리소스 / View Template)
- Server에서 Client로 Data를 전달하는 방법 ... 정적 리소스, View Template, HTTP Message Body 세 가지
- 정적 리소스 ... HTML, CSS, JS, Image 등을 변경 없이 그대로 반환
- View Template ... SSR을 사용할 때 View가 반환
- HTTP Message Body ... 응답 데이터를 직접 Message Body에 담아 반환
- 정적 리소스 ... 웹 애플리케이션에서 변하지 않는 파일들을 의미. (예, HTML, CSS, JavaScript, 이미지 파일(JPG, PNG, GIF) 등)
- Spring Boot의 정적 리소스 경로 ... 아래 경로들에 정적 리소스가 존재하면 서버에서 별도의 처리 없이 파일 그대로 반환된다.
- /static
- /public
- /META-INF/resources
- src/main/resources
- a. /static
- Spring Boot Directory 구조
- src/main/resources/static/hello/world.html 디렉토리 구조라면 http://localhost:8080/hello/world.html URL로 리소스에 접근이 가능.
- /static 대신 /public 혹은 /META-INF/resources 도 사용 가능
- View Template ... Spring에서는 Thymeleaf, JSP와 같은 템플릿 엔진을 사용해 View Template을 작성할 수 있고, View Template은 서버에서 데이터를 받아 이를 HTML 구조에 맞게 삽입한 후, 최종적으로 클라이언트에게 전송되는 HTML 문서로 변환하여 사용자에게 동적으로 생성된 웹 페이지를 제공
- View Template은 Model을 참고하여 HTML 등이 동적으로 만들어지고 Client에 응답됨
- Spring Boot는 기본적으로 View Template 경로(src/main/resources/templates)를 설정
- build.gradle에 Thymeleaf 의존성을 추가하면 ThymeleafViewResolver와 필요한 Spring Bean들이 자동으로 등록 됨
- 기본 설정 예시(아래 내용을 자동으로 Spring Boot가 등록해줌)
- @Controller의 응답으로 String을 반환하는 경우
- @ResponseBody가 없으면 View Resolver가 실행되며 View를 찾고 Rendering한다.
- URL 접속 시
- @ResponseBody가 있으면 HTTP Message Body에 return 문자열 값이 입력됨.
결과
- 반환 타입이 void인 경우 ... 잘 사용하지 않음. @Controller + (@ResponseBody, HttpServletResponse, OutputStream)과 같은 HTTP Message Body를 처리하는 파라미터가 없으면 RequestMapping URL을 참고하여 View Name으로 사용
- 예시와 같은 경우 viewTemplate(viewName)을 RequestMapping URL 주소로 찾음.
Spring 응답 데이터 2강 (HTTP Message Body(응답) / 정리)
- HTTP Message Body(응답) .. REST API를 만드는 경우 Server에서 Client로 HTML을 전달하는 방식이 아닌 HTTP Message Body에 직접 Data를 JSON 형식으로 담아 전달.
- 정적 HTML, View Template 또한 HTTP Message Body에 담겨서 전달됨.
- HTTP Message Body
- HttpServletResponse 사용
- Postman 호출 시
- Response Body에 data라는 문자열이 입력되어 응답 됨
- 기존 Servlet을 다룰 때 코드와 형태가 같음
- ResponseEntity<> 사용
- Postman 호출 시
- Response Body에 data라는 문자열과 HttpStatus.OK에 해당하는 상태 코드를 반환
- ResponseEntity는 HttpEntity를 상속 받음. HttpEntity는 HTTP Message의 Header, Body 모두 가지고 있음
- @ResponseBody(TEXT, JSON) 사용
- TEXT
- Postman 호출 시 data 출력
- JSON
- Postman 호출 시 Json 형태로 출력
- View를 사용하는 것이 아닌 HTTP Message Converter를 통해 HTTP Message Body를 직접 입력할 수 있음 -> ResponseEntity와 같음
- @ResponseStatus를 사용해 상태 코드를 지정할 수 있음
-> 호출 시 200 OK / json 데이터 출력 / 단, 응답 코드를 조건에 따라서 동적으로 변경할 수는 없음(예를 들어, 1번의 경우 OK, 2번의 경우 Created 출력 이런 거 안됨)
- @ResponseEntity< Object >(Json)
- Postman 호출 시
- ResponseEntity<> 두 번째 파라미터에 Enum을 사용하여 상태 코드를 바꿀 수 있음!
- HTTP Message Converter를 통해 JSON 형태로 변환되어 반환됨.
- 동적으로 응답 코드를 변경할 수 있음! (아래와 같이)
- ResponseEntity는 HttpEntity를 상속 받았음
- 정리
- Client에서 Server로 Data를 전달하는 세 가지 방법(Request)
- GET - Query Param, Query String (ex. http://localhost:8080/tutor?name=wonuk&age=100)
- 사용하는 어노테이션: @RequestParam, @ModelAttribute
- POST - HTML Form(x-www-form-urlencoded)
- 사용하는 어노테이션: @RequestParam, @ModelAttribute
- HTTP Request Body ... 데이터(JSON, TEXT, XML 등)를 직접 HTTP Message Body에 담아서 사용
- 사용하는 어노테이션: @RequestBody
- Server(Spring)에서 HTTP 응답을 Client에 전달하는 세 가지 방법(Response)
- 정적 리소스 ... HTML, CSS, JS, Image 등을 변경 없이 그대로 반환
- View Template ... SSR을 사용할 때 View가 반환
- 사용하는 어노테이션: @Controller
- HTTP Message Body ... 응답 데이터를 직접 Message Body에 담아 반환
- 사용하는 어노테이션: @ResponseBody, ResponseEntity< Object >
- 요청(Request) : C -> S
- @ReqeustParam, @ModelAttribute, @RequestBody
- 응답(Response) : S -> C
- 정적리소스, View Template(@Controller), ResponseBody, ResponseEntity< Object >
어렵다! Request가 좀 더 복잡하고 많은 느낌. 듣는 도중엔 무슨말인지 감이 안 잡혔는데, 쭉 듣다 보니까 결국 C와 S가 통신할 때 HTTP 규약(?)을 따르는데, Request(C to S), Response(S to C)를 어떻게 하는지에 대한 방법을 배웠던 것 같다. 아직 HTTP Method와 Spring에서 지원해주는 기능들이 어떻게 연결되는지 정리가 좀 덜된 느낌인데, 한번 정리해볼 필요가 있겠다. RequestParam, ModelAttribute, RequestBody / Controller, ResponseBody, ResponseEntity< Object > 등을 어떤 목적으로 어떻게 사용하는지 실제 사례에 비추어서 좀 뜯어봐야할 것 같다. 내일은 실습과 메모장 프로젝트 열심히 해보자!