[프로젝트] MessageConverter 적용하기

공부하는 감자·2024년 1월 24일
0

F-Lab 프로젝트

목록 보기
6/11

들어가는 말

프로젝트에서 Rest Controller를 만들었을 때, ResponseEntity 를 사용해 반환하고 있었다.

@PostMapping("/member")
ResponseEntity<MemberCreateResponse> createMember(@RequestBody MemberCreateRequest request) {
    Member member = memberService.createMember(memberMapper.toMember(request));
    return new ResponseEntity<>(memberMapper.toMemberCreateResponse(member), HttpStatus.CREATED);
}

내가 개발하는 것은 API 서버이기도 하고, MessageConverter를 사용해보는 것이 어떻겠냐는 피드백을 받아서 관련 내용을 검색 후 정리해봤다.

HTTP message converter란?

HTTP 요청 본문과 HTTP 응답 본문을 통째로 메세지로 다루는 방식이다.

  • Request body와 객체를 서로 변환해주는 역할을 수행함으로써, 개발자가 비즈니스 로직 작성에만 집중하도록 해준다.
  • 주로 XML이나 JSON을 이용한 AJAX기능이나 웹 서비스를 개발할 때 사용된다.
  • 스프링의 @RequestBody와 @ResponseBody를 통해 HTTP 메시지 컨버터를 자동 사용할 수 있다.
    • 혹은 HttpEntity(RequestEntity), HttpEntity(ResponseEntity)에서도 HTTP 메시지 컨버터가 적용된다.
    • 요청에 Body가 없는 경우에는 @RequestBody를 사용할 수 없고, 이 경우엔 @RequestParam이나 @ModelAttribute를 사용해야 한다.
  • HTTP message converter는 인터페이스로 되어있다.
    • String으로 변환하는 구현체: StringHttpMessageConverter
    • JSON으로 변환하는 구현체: MappingJackson2HttpMessageConverter

발동 조건

HTTP message converter는 다음과 같은 조건에서 실행된다.

  • @RequestBody, HttpEntity를 사용하는 경우 (= HTTP request)
    • Request body에 담긴 JSON 또는 String 데이터를 읽는 경우
  • @ResponseBody, HttpEntity를 사용하는 경우 (= HTTP response)
    • Response body에 JSON 또는 String 데이터를 담아 반환하는 경우

즉, HTTP message converter는 HTTP message body를 사용한 요청과 응답을 처리할 때 사용된다.

발동 시점

HTTP Reqeust

@RequestBody, HttpEntity(= RequestEntity)

  • Client로부터 들어온 request의 type이 application/json 형식인 경우, HTTP message converter가 호출된다.
  • HTTP message converter가 request body의 내용(= JSON)을 읽는다.
  • 읽어온 JSON을 HttpEntity 객체 또는 @RequestBody와 함께 사용된 Model 객체로 변환한다.

HTTP Response

@ResponseBody, HttpEntity(= ResponseEntity)

  • 메서드에서 @ResponseBody 또는 HttpEntity를 사용하거나 Model 객체를 반환하는 경우, message converter가 호출된다.
  • 메서드의 반환 값이 HTTP message converter에게 전달된다.
  • HTTP message converter는 해당 객체를 JSON 형식으로 변환하여 Client에게 전달한다.

메시지 컨버터 자동생성

스프링 부트를 사용할 경우, 메시지 컨버터는 자동 생성된다.

  • BackgroundPreinitializer 클래스: 내부적으로 MessageConverter를 생성하여 실행시킨다.

자동생성된 메시지 컨버터 종류

  1. ByteArrayHttpMessageConverter : byte[] 데이터를 처리한다
    • 미디어타입은 모든 것을 다 지원한다.
    • 즉,요청 파라미터에 @RequestBody byte[] param과 같이 작성하면 모든 요청을 다 byte배열로 받을 수 있다는 말이다.
    • 응답 리턴타입을 byte[]로 했을 경우 Content-Type이 applcation/octet-stream으로 설정되어 전달된다.
    • 파일 및 이미지 다운로드/업로드일때 쓰인다고 한다.
  2. StringHttpMessageConverter : String 문자로 데이터를 처리한다.
    • 미디어타입은 모든 것을 다 지원한다.
    • 요청 파라미터에 사용할 경우 HTTP 본문을 그대로 String으로 가져올 수 있다.
    • 응답 리턴에 사용할 경우 단순 문자열을 그대로 전달해줄 수 있다. Content-Type은 text/plain
  3. SourceHttpMessageConvreter
    • 미디어타입은 모든 것을 다 지원한다.
    • Content-Type이 application/octet-stream를 지원한다. 알려지지않은 파일 타입은 이타입을 사용한다.
    • 브라우저들은 이런 파일들을 다룰 때, 사용자를 위험한 동작으로부터 보호하도록 개별적인 주의를 기울여야 한다.
  4. FormHttpMessageConverter
    • 보이다시피, 지원하는 미디어 타입은 MediaType.APPLICATION_FORM_URLENCODEDMediaType.MULTIPART_FORM_DATA,MediaType.MULTIPART_MIXED이다.
    • 즉, 정의된 폼 데이터를 주고받을 때 사용할 수 있다
  5. MappingJackson2HttpMessageConverter
    • 미디어타입은 MediaType.APPLICATION_JSON만 지원한다.
    • Jackson의 objectMapper를 이용하여 JSon를 변환한다.
    • 변환하는 오브젝트 타입의 제한은 없지만, 프로퍼티를 가진 자바빈 스타일(커스텀 객체)이나 HashMap을 이용해야 정확한 변환 결과를 얻을 수 있다.

맺는 말

@ResponseBody 를 사용하면, 반환하는 것이 객체일 경우 JSON으로 반환된다고 한다.

따라서, 나는 @ResponseBody 어노테이션을 사용하도록 수정했다.

@PostMapping("/member")
@ResponseBody
MemberCreateResponse createMember(@RequestBody MemberCreateRequest request) {
    Member member = memberService.createMember(memberMapper.toMember(request));
    return memberMapper.toMemberCreateResponse(member);
}

Reference

참고 사이트

SpringMVC 에서 말하는 MessageConverter 코드로 이해하기

HTTP 메시지를 spring에서 사용하기 쉽게 만들어 주는 MessageConverter

18. HTTP message converter

profile
책을 읽거나 강의를 들으며 공부한 내용을 정리합니다. 가끔 개발하는데 있었던 이슈도 올립니다.

0개의 댓글

관련 채용 정보