Spring

HttpMessageConverter 간단 정리

꾸준함. 2021. 6. 11. 17:52

1. HttpMessageConverter 용도

  • HTTP API처럼 JSON 데이터를 HTTP 메시지 바디 내 직접 읽거나 쓰는 경우 사용
  • @ResponseBody 어노테이션을 사용할 때 HTTP Body 내 문자 내용을 직접 반환하므로 HttpMessageConverter가 동작
  • String 문자 처리에는 StringHttpMessageConverter, 객체 처리에는 MappingJackson2HttpMessageConverter 사용
  • 이외에도 다양한 HttpMessageConverter가 존재

 

* 응답의 경우 클라이언트의 HTTP Accept 헤더서버 컨트롤러의 반환 타입을 조합해 MessageConverter가 선택됨 (하단에 추가 설명)

 

2. 스프링 MVC의 HttpMessageConverter 적용 사례

  • HTTP 요청: @RequestBody, HttpEntity(RequestEntity)
  • HTTP 응답: @ResponseBody, HttpEntity(ResponseEntity)

 

3. HttpMessageConverter 인터페이스 뜯어보기


 

* canRead(), canWrite() 메서드: 메시지 컨버터가 해당 클래스 혹은 미디어타입을 지원하는지 체크하는 용도

* read(), write() 메서드: 메시지 컨버터를 통해서 메시지를 읽고 쓰는 기능 지원

 

3.1 HTTP 요청 데이터 읽는 과정

  • HTTP 요청이 들어오고, 컨트롤러에서 @RequestBody 혹은 HttpEntity 파라미터 사용하는 상황
  • MessageConverter가 메시지를 읽을 수 있는 확인하기 위해 canRead() 메서드 호출 (대상 클래스 타입을 지원하는지, HTTP 요청의 Content-Type 미디어 타입을 지원하는지 체크)
  • canRead() 조건을 만족할 경우 read() 메서드를 호출해서 객체 생성 후 반환

 

3.2 HTTP 응답 데이터 생성하는 과정

  • 컨트롤러에서 @ResponseBody 혹은 HttpEntity로 값이 반환되는 상황
  • MessageConverter가 메시지를 쓸 수 있는지 확인하기 위해 canWrite() 메서드 호출 (대상 클래스 타입을 지원하는지, HTTP 요청의 Accept 미디어 타입을 지원하는지 체크)
  • canWrite() 조건을 만족할 경우 write() 메서드를 호출해서 HTTP 응답 메시지 바디 내 데이터 생성

 

4. 주로 사용하는 메시지 컨버터 세 가지 (우선순위 순)

  • ByteArrayHttpMessageConverter
  • StringHttpMessageConverter
  • MappingJackson2HttpMessageConverter

 

* 앞서 언급한 대로 스프링에서 메시지 컨버터를 선정할 때 대상 클래스 타입과 미디어 타입을 체크 후 사용 여부를 결정하고, 만족하지 않을 경우 다음 우선순위에 있는 메시지 컨버터로 넘어가 체크 진행

 

4.1 ByteArrayHttpMessageConverter

  • byte [] 데이터 처리
  • 클래스 타입: byte []
  • 미디어 타입: */*
  • HTTP 요청 예시: @RequestBody byte [] example
  • HTTP 응답 예시: @ResponeBody return byte[] (쓰기 MediaType: application/octet-stream)

 

4.2 StringHttpMessageConverter

  • String 문자열로 데이터 처리
  • 클래스 타입: String
  • 미디어 타입: */*
  • HTTP 요청 예시: @RequestBody String example
  • HTTP 응답 예시: @ResponseBody return example (쓰기 MediaType: text/plain)

 

 

 

 

4.3 MappingJackson2HttpMessageConverter

  • application/json 처리
  • 클래스 타입: 객체 또는 HashMap
  • 미디어 타입: application/json
  • HTTP 요청 예시: @RequestBody Example example
  • HTTP 응답 예시: @ResponseBody return example (쓰기 MediaType: application/json)


 

4.4 오류가 나는 경우


 

* 대상 클래스 타입과 미디어 타입이 매칭이 안되기 때문에 오류가 발생

 

HttpMessageConverter가 쓰이는 시점?

 

우선, 기존 게시물에서 작성한 Spring MVC 구조를 살펴봅시다. (https://jaimemin.tistory.com/1820)

 

Spring MVC 구조

 

* 위 그림에서는 HttpMessageConverter가 쓰이는 시점이 보이지 않지만, HttpMessageConverter는 아래 사진처럼 @RequestMapping을 처리하는 HandlerAdapter인 RequestMappingHandlerAdapter에서 쓰입니다.

 

HttpMessageConverter가 쓰이는 시점

 

  • 어노테이션 기반 컨트롤러는 HttpServletRequest, Model, @RequestParam, @ModelAttribute, @RequestBody, HttpEntity와 같이 다양한 파라미터를 사용할 수 있는데 이렇게 유연하게 처리해줄 수 있는 이유는 ArgumentResovler 덕분
  • 즉, 컨트롤러를 처리하는 RequestMappingHandlerAdapter가 ArgumentResolver를 호출하면서 필요로 하는 다양한 파라미터의 값을 생성한 후 컨트롤러를 호출하며 파라미터를 넘겨줌 (사진 내 1번과 2번 과정)
  • ReturnValueHandler는 응답 값을 변환하고 처리하는데, 컨트롤러에서 String으로 뷰의 논리적 이름만 반환하더라도 동작하는 이유가 ReturnValueHandler 덕분 (사진 내 3번 과정)
  • 이 과정에서 HttpMessageConverter는 요청과 응답을 처리하는 과정에서 모두 필요한데 아래와 같은 상황에서 사용이 됨
    • 요청: @RequestBody 혹은 HttpEntity를 처리하는 ArgumentResovler가 HttpMessageConverter를 사용해서 필요하는 객체를 생성
    • 응답: @ResponseBody 혹은 HttpEntity를 처리하는 ReturnValueHandler에서 HttpMessageConverter를 사용해서 응답 결과 생성

 

출처

인프런 스프링 MVC 1편 (김영한 강사님)

반응형