SPRING

[SPRING] HTTP 메세지 컨버터

steadyMan 2022. 4. 3. 19:13

Spring 사용 시 HTML 파일을 응답하는 게 아닌 HTTP API처럼 JSON 데이터를 HTTP메시지 바디에 입력하거나  문자열을 입력할 HTTP 메시지 컨버터를 사용하면 편리하다. 

 

개인적인 학습의 정리글입니다.

 

스프링 MVC는 다음의 경우에 HTTP 메시지 컨버터를 적용한다. 

HTTP 요청 

  • @RequestBody
  • HttpEntity(RequestEntity)

HTTP 응답 

  • @ResponseBody
  • HttpEntity(ResponseEntity)

HTTP 메세지 컨버터 인터페이스를 보면 

canRead(), canWrite()로 메세지 컨버터가 해당 클래스, 미디어 타입을 지원하는지 확인하고 

HttpMessageConverter Interface

read(), write() : 메시지 컨버터를 통해서 메세지를 읽고 쓰는 메소드 

스프링에는 HTTP 메세지 컨버터 인터페이스의 다양한 구현체가 있는데 대상 클래스 타입과 미디어 타입(클라이언트)을 확인해서 

사용 여부를 결정한다. 사용조건을 만족하지 못하면 다음 메시지 컨버터로 우선순위가 넘어간다. 

주로 사용되는 주요 메세지 컨버터 

ByteArrayHttpMessageConverter 

클래스 타입 : byte[]

미디어 타입(content-Type) : */*(모든타입 가능)

요청 예) @RequestBody byte[] data 

응답 예) @ResponseBody return byte[] 

미디어타입 : application/octet-stream(반환 미디어 타입)

StringHttpMessageConverter 

클래스 타입 : String

미디어타입 : */*(모든타입 가능)

요청 예) @RequestBody String data 

응답 예) @ResponseBody return "response"

리턴 미디어타입 : text/plain(반환 미디어 타입)

MappingJackson2HttpMessageConverter 

클래스 타입 : Object 또는 HashMap

미디어타입 : application/json 

요청 예) @RequestBody HelloData helloData

응답 예) @ResponseBody return helloData

리턴 미디어타입 : application/json

클래스 타입과 미디어타입이 정상적이지 않을경우? 

MappingJackson2HttpMessageConverter 적용

위의 경우 @RequestBody 클래스 타입이 Object이기 떄문에 미디어 타입이 application/json여야 하지만 

Content-Type을 text/plain으로 요청해보면 

HTTP 415 상태코드

415 상태코드가 리턴되게 된다. 

HTTP 요청 데이터 읽기의 과정 

HTTP 요청이 오고 컨트롤러에서 @RequestBody 혹은 HttpEntity 파라미터를 사용할 경우 

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

@RequestBody(메세지 컨버터의 대상)과

    - byte[], String, Object

Content-Type 미디어 타입 지원여부 확인하고 

    - text/plain, application/json, */*

canRead() 조건을 만족하면 read() 호출하여 객체생성후 반환된다.

HTTP 응답 데이터 생성의 과정 

1. 컨트롤러에서 반환타입이 @ResponseBody, HttpEntity 이라면 

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

  클래스 타입 지원 여부 확인과

    - byte[], String, Object

  Http 요청의 Accept 미디어타입 지원 여부 확인 후

    - text/plain, application/json, */*

3. canWrite() 조건이 만족되면 write()를 호출하여 HTTP 응답 메세지 바디에 데이터 생성된다.

 

 

막연하게 사용할때는 몰랐지만 클래스 타입과 Content-Type을 기준으로 분기가 된다는 사실을 알게되었으니 

더욱 정확하게 사용이 가능해졌다.