[Spring]HttpMessageConverter

2025. 4. 16. 13:56·Spring

✅ HttpMessageConverter 1장

♐ HttpMessageConverter란?

  • View를 응답하는 것이 아닌, Rest API(HTTP API)로 JSON, TEXT, XML 등의 데이터를 응답 Message Body에 직접 입력하는 경우 HttpMessageConverter를 사용

 

♐ 동작 원리

 

 

♐ 적용 케이스

  • 1. HTTP 요청 : `@RequestBody`, `HttpEntity<>`,  `RequestEntity<>` 
  • 2. HTTP 응답 : `@ResponseBody`, `HttpEntity<>`, `ResponseEntity<>`
즉, HttpMessageConverter`는 요청과 응답 모두 사용된다

 

 

♐ 우선 순위

  • Spring은 다양한 HttpMessageConverter를 제공하고 있고 우선순위가 있다. 대상 Class와 MediaType을 체크해서 어떤 Converter를 사용할지 결정한다.

1️⃣ ByteArrayHttpMessageConverter

  • byte[] Data 를 처리한다.
  • 대상 : byte[]
  • MediaType : */*
@Slf4j
@RestController // @Controller + @ResponseBody
public class MessageConverterController {

		// 요청 헤더 -> content-type: */*
		@PostMapping("/byte-array")
		// byte[] -> produces = "application/octext-stream"
		public byte[] byteArray(@RequestBody byte[] data) {
			log.info("byte-array logic");
			return data; // response
		}
		
}

 

 

 2️⃣ StringHttpMessageConverter

  • String Data를 처리한다.
  • 대상: String
  • MediaType : */*
// 요청 헤더 -> content-type: text/plain
@PostMapping("/string")
// String -> produces = "text/plain"
public String string(@RequestBody String data) {
	log.info("string logic");
	return data;
}

 

3️⃣ MappingJackson2HttpMessageConverter

  • `JSON` Data를 처리한다.
  • 대상 : `Object`, `HashMap`
  • MediaType : `application/json`
// 요청 헤더 content-type: application/json
@PostMapping("/json")
// Data -> produces = "application/json"
public Data json(@RequestBody Data data) {
		log.info("json logic");
		return data;
}

 

 

♐ 동작 순서

 

1️⃣ 요청 데이터 읽기

  1. 요청
  2. Controller에서 @RequestBody 혹은 HttpEntity<>로 파라미터 바인딩한다.
  3. `MessageConverter`는 `canRead()` 메서드로 읽기가능 여부를 조회한다.
        - 대상 클래스가`byte[], String, Object` 인지 여부 확인
        - 요청 헤더의 `Content-Type` Media Type 지원여부 확인(`consumes`)
  4. read() 메서드를 호출하여 Object를 생성한다.

2️⃣ 응답 데이터 읽기

  1. Controller에서 @ResponseBody 혹은 HttpEntity<>로 응답이 반환된다.
  2. MessageConverter는 canWrite() 메서드로 사용가능 여부를 조회한다.
  3. write() 메서드를 호출하여 HTTP Response Message Body에 데이터를 입력한다.

 

✅ 실습해보기

♐ 첫번째 실습(성공)

  • content-type : `applicatin/json`
  • @RequestBody : `String`
@PostMapping("/json-to-text")
// String -> produces = "text/plain"
public String jsonToText(@RequestBody String data) {
	// logic
	return data;
}

 

1. ByteArrayHttpMessageConverter 의 canRead() 메서드 호출 :  false

2. StringHttpMessageConverter 의 canRead() 메서드 호출 : true

3. 우선순위에 밀려서 MappingJackson2HttpMessageConverter 는 동작하지 않는다.

 

 

♐ 두번째 실습(성공)

  • content-type : `applicatin/json`
  • @RequestBody : `Object`
@Data
public class DataDto {
    private final String key;
}

@PostMapping("/json-to-json")
// Object -> produces = "application/json"
public DataDto jsonToJson(@RequestBody DataDto dto) {
	// logic
	return dto;
}

 

1. ByteArrayHttpMessageConverter 의 canRead() 메서드 호출 : false

2. StringHttpMessageConverter 의 canRead() 메서드 호출 : false

3. MappingJackson2HttpMessageConverter 의 canRead() 메서드를 호출 : true

 

♐ 세번째 실습(실패)

  • content-type : `text/plain`
  • @RequestBody : `Object`
// "{\"key\": \"value\"}"
@PostMapping("/text-to-json")
// Object -> produces = "application/json"
public DataDto textToJson(@RequestBody DataDto dto) {
	// logic
	return dto;
}

 

1.ByteArrayHttpMessageConverter 의 canRead() 메서드 호출 : false

2.StringHttpMessageConverter 의 canRead() 메서드 호출 : false

3.MappingJackson2HttpMessageConverter 의 canRead() 메서드 호출 : false

 

 

✅ HttpMessageConverter 2장

♐ HttpMessageConverter 의 사용 구조

 

  • 요청시에는 Argument Resolver가 사용하는것이다.
  • 응답시에는 ReturnValueHandler가 사용한다.

♐ 대표적인 Argument Resolver , ReturnValueHandler

 

 

1️⃣ RequestResponseBodyMethodProcessor 

  • @RequestBody, @ResponseBody  를 모두 처리 가능

 

 

- HandlerMethodArgumentResolver 상속
- HandlerMethodReturnValueHandler 상속


- 즉,@RequestBody`, `@ResponseBody` 두가지 모두 처리하기위해 둘다 상속

 

2️⃣ HttpEntityMethodProcessor

  • HttpEntity<> 를 사용하기 위해 사용

 

- `HandlerMethodArgumentResolver` 상속
- `HandlerMethodReturnValueHandler` 상속
 

  - 즉,`HttpEntity<>` 를 상속받은 `RequestEntity<>` , `ResponseEntity<>` 모두 처리

 

3️⃣HttpEntityMethodProcessor.supportParameter()

  • HttpEntity<> 혹은 HttpEntity를 상속받은 객체 여부 확인

 

4️⃣HttpEntityMethodProcessor.resolveArgument()

  • 실제 Object로 만들어주는 메서드
  • readWithMessageConverters(webRequest, parameter, paramType);
  • 위 코드를 실행하여 코드 내부에서 `MessageConverter` 호출하여 값을 처리한다.

 

💡ArgumentResolver 와 HttpMessageConverter 는 다르다.

 

 

♐ HttpMessageConverter 의 확장

  • WebMvcConfigurer를 상속받고 Spring Bean으로 등록
  • @Configuration를 이용하여 Spring Bean으로 등록

예시코드

더보기
public interface WebMvcConfigurer {
    default void configurePathMatch(PathMatchConfigurer configurer) {
    }

    default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    }

    default void configureAsyncSupport(AsyncSupportConfigurer configurer) {
    }

    default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    }

    default void addFormatters(FormatterRegistry registry) {
    }

    default void addInterceptors(InterceptorRegistry registry) {
    }

    default void addResourceHandlers(ResourceHandlerRegistry registry) {
    }

    default void addCorsMappings(CorsRegistry registry) {
    }

    default void addViewControllers(ViewControllerRegistry registry) {
    }

    default void configureViewResolvers(ViewResolverRegistry registry) {
    }

    default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
    }

    default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
    }

    default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    }

    default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    }

    default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    }

    @Nullable
    default Validator getValidator() {
        return null;
    }

    @Nullable
    default MessageCodesResolver getMessageCodesResolver() {
        return null;
    }
}

 

 

 

'Spring' 카테고리의 다른 글

[Spring/JPQL] JPQL이 무엇인지 알고 사용하자  (1) 2025.04.18
[Spring]Converter 보다 세부적으로 타입변경하는 법  (0) 2025.04.16
[SPRING/JPA]양방향 관계시 사용하는 CASCADE에 대해 알아보자  (1) 2025.04.11
[Spring/JPA] 영속성 컨텍스트  (0) 2025.04.11
[Spring] Annotation  (2) 2025.04.10
'Spring' 카테고리의 다른 글
  • [Spring/JPQL] JPQL이 무엇인지 알고 사용하자
  • [Spring]Converter 보다 세부적으로 타입변경하는 법
  • [SPRING/JPA]양방향 관계시 사용하는 CASCADE에 대해 알아보자
  • [Spring/JPA] 영속성 컨텍스트
코딩로봇
코딩로봇
금융 IT 개발자
  • 코딩로봇
    쟈니의 일지
    코딩로봇
  • 전체
    오늘
    어제
    • 분류 전체보기 (133) N
      • JavaScript (8)
      • SQL (10)
      • 코딩테스트 (29)
        • Java (15)
        • SQL (12)
      • Java (10)
      • 프로젝트 (21) N
        • 트러블슈팅 (7) N
        • 프로젝트 회고 (12)
      • git,Github (2)
      • TIL (35) N
      • Spring (16)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스파르타 코딩 #부트캠프 #첫ot
    java #arraylist #list #배열
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코딩로봇
[Spring]HttpMessageConverter
상단으로

티스토리툴바