본문 바로가기
IT 개인 공부/Spring

[Spring] HTTP 메시지 컨버터

by Libi 2021. 9. 3.
반응형

클라이언트에서 서버로 요청 데이터를 전달할 때는 주로 다음과 같은 방법을 통해 전달한다.

  • GET + 쿼리 파라미터
  • POST - HTML Form
  • HTTP Message Body

 

반대로 서버에서 클라이언트에 응답 데이터를 전달할 때는 다음과 같다.

  • 정적/동적 HTML
  • HTTP Message Body

 

HTTP API를 제공하는 경우에는 HTTP Message Body에 JSON, XML, TEXT 형식으로 데이터를 직접 담아서 요청 및 응답을 처리한다.

Spring에서는 HttpEntity 객체나 @RequestBody, @ResponseBody 어노테이션을 사용하면 데이터를 직접 매핑할 필요 없이 자동으로 요청 및 응답 데이터를 적절한 데이터 형식으로 변환해준다.

@Slf4j
@Controller
@RequestMapping("/test")
public class Test {

    @ResponseBody
    @PostMapping("/httpEntity")
    public String httpEntity(HttpEntity<Hello> data) {
        log.info("Http Header={}", data.getHeaders());
        log.info("Http Body={}", data.getBody());
        return "ok";
    }

    @ResponseBody
    @PostMapping("responseBody")
    public String responseBody(@RequestBody Hello data) {
        log.info("data={}", data);
        return "ok";
    }

    @Data
    static class Hello {
        private String name;
        private int age;
    }
}

 

실제로 JSON 형식의 데이터를 날려보면 별다른 매핑을 구현하지 않아도 원하는 대로 처리되는 것을 확인할 수 있다.

 

그렇다면 스프링은 내부에서 어떠한 원리로 요청 및 응답 데이터를 적절한 데이터로 변환해주는 것일까?

이는 HTTP 메시지 컨버터라는 기능을 통해서 제공해준다.

 

HTTP 메시지 컨버터는 데이터의 클래스 타입과 미디어 타입을 체크하여 알맞은 형식의 데이터로 변환해주는 친구이다.

  • canRead(), canWrite() : 메시지 컨버터가 데이터의 클래스 타입과 미디어 타입을 지원하는지 확인
  • read(), write() : 지원한다면 메시지를 적절한 데이터로 변환(읽기, 쓰기)

 

스프링 부트는 다양한 타입의 메시지 컨버터를 지원하며 이들은 우선순위를 가진다.

대표적인 메시지 컨버터는 다음과 같다.

  • ByteArrayHttpMessageConverter(우선순위 0)
  • StringHttpMessageConverter(우선순위 1)
  • MappingJackson2HttpMessageConverter(우선순위 2)

 

만약, JSON 형식의 객체 데이터 {"name":"hello", "age":20}를 전송하면 MappingJackson2HttpMessageConverter가 적절한 데이터로 변환해준다.

MappingJackson2HttpMessageConverter는 클래스 타입으로 객체 or HashMap을 지원하고, 미디어 타입으로 application/json을 지원해주기 때문이다.

 

HTTP 메시지 컨버터의 동작원리는 이해하였다. 그렇다면 HTTP 메시지 컨버터는 스프링 MVC의 동작 과정 중 어디서 적용되는 것일까?

HTTP 메시지 컨버터는 ArgumentResolverReturnValueHandler가 사용한다.

 

스프링 MVC는 요청이 발생하면 핸들러 매핑, 핸들러 어댑터를 통해 요청을 처리할 수 있는 컨트롤러를 찾아준다.

그런데 우리는 요청을 @RequestParam, @ModelAttribute, @RequestBody, HttpEntity 등 다양한 타입의 인자값으로 받을 수 있었다.

컨트롤러에서 데이터를 사용하기 위해서는 다양한 타입의 인자값을 누군가가 적절한 데이터로 매핑시켜줘야 할 것이다.

이를 해결해주는 친구가 바로 ArgumentResolver이다. 반대로 ReturnValueHandler는 응답에서 다양한 타입의 인자값을 처리해준다.

 

즉, ArgumentResolver와 ReturnValueHandler는 요청, 응답 데이터를 적절한 데이터로 변환해주는 역할을 수행한다.

이때 다양한 타입의 데이터들 중 HttpEntity 객체나 @RequestBody, @ResponseBody 어노테이션을 가지는 데이터라면 HTTP 메시지 컨버터를 사용하여 데이터를 매핑시켜주는 것이다.

 

 

 

[ Reference ]

· https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard

반응형

댓글