스프링 공부 (인프런 김영한 선생님)/스프링 MVC 1편

[스프링 웹 MVC 1편] 26. HTTP 메세지 컨버터

2023. 6. 4. 16:03

@RequestBody를 컨트롤러 메서드단에 적용하면 HTTP 메세지 바디에 그대로 String 문자열이나,

ResponseEntity의 인자로 객체를 반환하면 JSON으로 문자열을 반환하면 OK와 같은 문자열을 그대로 입력할 수 있다.

 

응답으로 객체/문자열을 처리하는 방법은 이전 시간에 논의한 내용을 참고하자

 

https://progyun.tistory.com/209

 

[스프링 웹 MVC 1편] 25. HTTP 응답 - HTTP API, 메세지 바디에 직접 입력

package hello.springmvc.basic.response; import hello.springmvc.basic.HelloData; import java.io.IOException; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframew

progyun.tistory.com

이때 viewResolver 대신 HttpMessageConverter가 동작하게 되는데 이 인터페이스의 구체 클래스로

1)  기본 문자처리를 위한 StringHttpMessageConverter

2)  기본 객체처리를 위한 MappingJackson2HttpMessageConverter

3)  이외에도 바이트 코드 등 기타 HttpMessageConverter가 등록되어 있다.

 

응답의 경우 클라이언트의 HTTP Accept Header와 서버 컨트롤러의 반환 타입 정보 둘을 조합해서 HttpMessageConverter가 선택됨.

 

스프링 MVC는 다음 경우에 HTTP 메세지 컨버터를 적용함

-> HTTP 요청 : @RequestBody, HttpEntity(RequestEntity)

-> HTTP 응답 : @ResponseBody, HttpEntity(ResponseEntity)

 

/*
 * Copyright 2002-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.http.converter;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;

/**
 * Strategy interface for converting from and to HTTP requests and responses.
 *
 * @author Arjen Poutsma
 * @author Juergen Hoeller
 * @author Rossen Stoyanchev
 * @since 3.0
 * @param <T> the converted object type
 */
public interface HttpMessageConverter<T> {

 /**
  * Indicates whether the given class can be read by this converter.
  * @param clazz the class to test for readability
  * @param mediaType the media type to read (can be {@code null} if not specified);
  * typically the value of a {@code Content-Type} header.
  * @return {@code true} if readable; {@code false} otherwise
  */
 boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);

 /**
  * Indicates whether the given class can be written by this converter.
  * @param clazz the class to test for writability
  * @param mediaType the media type to write (can be {@code null} if not specified);
  * typically the value of an {@code Accept} header.
  * @return {@code true} if writable; {@code false} otherwise
  */
 boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

 /**
  * Return the list of media types supported by this converter. The list may
  * not apply to every possible target element type and calls to this method
  * should typically be guarded via {@link #canWrite(Class, MediaType)
  * canWrite(clazz, null}. The list may also exclude MIME types supported
  * only for a specific class. Alternatively, use
  * {@link #getSupportedMediaTypes(Class)} for a more precise list.
  * @return the list of supported media types
  */
 List<MediaType> getSupportedMediaTypes();

 /**
  * Return the list of media types supported by this converter for the given
  * class. The list may differ from {@link #getSupportedMediaTypes()} if the
  * converter does not support the given Class or if it supports it only for
  * a subset of media types.
  * @param clazz the type of class to check
  * @return the list of media types supported for the given class
  * @since 5.3.4
  */
 default List<MediaType> getSupportedMediaTypes(Class<?> clazz) {
  return (canRead(clazz, null) || canWrite(clazz, null) ?
    getSupportedMediaTypes() : Collections.emptyList());
 }

 /**
  * Read an object of the given type from the given input message, and returns it.
  * @param clazz the type of object to return. This type must have previously been passed to the
  * {@link #canRead canRead} method of this interface, which must have returned {@code true}.
  * @param inputMessage the HTTP input message to read from
  * @return the converted object
  * @throws IOException in case of I/O errors
  * @throws HttpMessageNotReadableException in case of conversion errors
  */
 T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
   throws IOException, HttpMessageNotReadableException;

 /**
  * Write a given object to the given output message.
  * @param t the object to write to the output message. The type of this object must have previously been
  * passed to the {@link #canWrite canWrite} method of this interface, which must have returned {@code true}.
  * @param contentType the content type to use when writing. May be {@code null} to indicate that the
  * default content type of the converter must be used. If not {@code null}, this media type must have
  * previously been passed to the {@link #canWrite canWrite} method of this interface, which must have
  * returned {@code true}.
  * @param outputMessage the message to write to
  * @throws IOException in case of I/O errors
  * @throws HttpMessageNotWritableException in case of conversion errors
  */
 void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
   throws IOException, HttpMessageNotWritableException;

}

 

HTTP 메세지 컨버터는 HTTP 요청, HTTP 응답 모두에 의해 사용됨

-> canRead(), canWrite()를 통해 메세지 컨버터가 해당 클래스나 미디어타입(consumes, produces)를 지원하는지 체크

-> read(), write() 메세지 컨버터를 통해서 메세지를 읽고 쓰는 기능

 


스프링 부트 기본 메세지 컨버터

0 - ByteArrayHttpMessageConverter

1 - StringHttpMessageConverter

2 = MappingJackson2HttpMessageConverter : application/json

 

- 스프링 부트의 다양한 메세지 컨버터 중 일부를 서술한 것이다

대상 클래스 타입과 미디어타입(content-type) 둘을 체크해서 사용 여부를 결정하게 된다.

만족하지 않는 경우 다음 메세지 컨버터로 우선순위가 넘어간다.

 

1) ByteArrayMessageConverter : byte[] 데이터를 처리한다.

- 클래스 타입 String, 미디어 타입 : */*

요청 예시) @RequestBody byte[] java

응답 예시) @ResponseBody return byte[] / 미디어 타입 : application/octet-stream

 

2) StringHttpMessageConverter : String 문자로 데이터를 처리한다

- 클래스 타입 : String, 미디어타입 : */*

요청 예시) @RequestBody String data

응답 예시) @ResponseBody return "ok" / 미디어 타입 text-plain

 

3) MappingJackson2HttpMessageConverter: application/json

- 클래스 타입: 객체 또는 HashMap, 미디어 타입: application/json 관련

요청 예시 : @RequestBody HelloData data

응답 예시 : @ResponseBody return helloData / 미디어 타입 application/json 관련

 

헷갈렸던 내용이 요청 응답 어떻게 구분할 것인가였는데

이제 보니 요청 데이터 관련의 경우 메서드의 파라미터 단으로 HttpEntity나 @RequestBody가 들어가고

응답 데이터 관련한 경우는 HttpEntity나 @ResponseBody로 값이 반환된다.

 


HTTP 요청 데이터 읽기

- HTTP 요청이 오고, 컨트롤러에서 @RequestBody HttpEntity 파라미터를 사용한다.

- 메세지 컨버터가 메세지를 읽을 수 있는지 확인하기 위해 canRead()를 호출한다.

-> 대상 클래스 타입을 지원하는가? (예) @RequestBody의 대상 클래스가 byte[]인지 String인지 HelloData인지

-> HTTP 요청의 Content-Type 미디어 타입을 지원하는가 (예) text/plain, application/json, */*

- canRead() 조건을 만족하는 read()를 호출하고 객체 생성하고, 반환한다.

 

HTTP 응답 데이터 생성

- 컨트롤러에서 @ResponseBody, HttpEntity로 값이 반환된다

- 메세지 컨버터가 메세지를 쓸 수 있는지 확인하기 위해, canWrite()를 호출한다.

-> 대상 클래스 타입을 지원하는가? (예) return의 대상 클래스가 byte[]인지 String인지 HelloData인지

-> HTTP 요청의 Accept 미디어 타입을 지원하는가 / 더 자세히는 @RequestMapping의 produces

= 클라이언트가 읽을 수 있는 자료의 출력이 필요하기 때문이다

(예) text/plain, application/json, */*

- canWrite() 조건을 만족하는 write()를 호출해서 HTTP 응답 메세지 바디에 데이터를 생성한다.

 

==> 만약 세가지가 다 탈락하게 되면 에러가 발생한다.

 

 

'스프링 공부 (인프런 김영한 선생님) > 스프링 MVC 1편' 카테고리의 다른 글

[스프링 웹 MVC 1편] 27. 요청 매핑 핸들러 어댑터 구조  (0) 2023.06.05
[스프링 웹 MVC 1편] 25. HTTP 응답 - HTTP API, 메세지 바디에 직접 입력  (0) 2023.06.04
[스프링 웹 MVC 1편] 24. HTTP 응답 - 정적 리소스, 뷰 템플릿  (0) 2023.06.04
[스프링 웹 MVC 1편] 23. HTTP 요청 파라미터 (JSON)  (0) 2023.06.03
[스프링 웹 MVC 1편] 22. HTTP 요청 파라미터 (@ModelAttribute, 단순 텍스트)  (0) 2023.06.03
'스프링 공부 (인프런 김영한 선생님)/스프링 MVC 1편' 카테고리의 다른 글
  • [스프링 웹 MVC 1편] 27. 요청 매핑 핸들러 어댑터 구조
  • [스프링 웹 MVC 1편] 25. HTTP 응답 - HTTP API, 메세지 바디에 직접 입력
  • [스프링 웹 MVC 1편] 24. HTTP 응답 - 정적 리소스, 뷰 템플릿
  • [스프링 웹 MVC 1편] 23. HTTP 요청 파라미터 (JSON)
ProgYun.
ProgYun.
인내, 일관성, 그리고 꾸준함을 담습니다.
ProgYun.
Perseverance, Consistency, Continuity
ProgYun.
전체
오늘
어제
  • 분류 전체보기
    • 칼럼
    • 일상생활
      • 월별 회고
      • 인생 이야기 (대학생활)
      • 취준
      • 운동인증
      • 제품 사용 후기와 추천
    • 스프링 공부 (인프런 김영한 선생님)
      • 스프링 핵심원리
      • 스프링 MVC 1편
      • 스프링 MVC 2편
    • 면접 준비
    • 전공
      • OOP 정리
      • Design Pattern
    • 스터디
    • English
      • Electronics(Laptop)
      • 1일 1단어

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 확진자
  • mason
  • ssd
  • 컴공
  • NVME
  • 오미크론
  • 대학생
  • 윈도우재설치
  • 윈도우10
  • 피로그래밍
  • 코로나
  • 편입생
  • 자가격리
  • 하이닉스
  • 코로나19
  • p31
  • 포맷
  • 해외직구
  • 자존감
  • 일상

최근 댓글

최근 글

hELLO · Designed By 정상우.
ProgYun.
[스프링 웹 MVC 1편] 26. HTTP 메세지 컨버터
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.