본문 바로가기
Spring/10. rest-api

HttpMessageConverter

by 989898 2025. 3. 14.

Spring의 HttpMessageConverterHTTP 요청과 응답의 본문(body)을 Java 객체로 변환하거나 (역직렬화), Java 객체를 HTTP 메시지 본문으로 변환하는 역할을 합니다. (직렬화) 특히 JSON 데이터를 처리할 때 매우 유용하며, Spring은 내부적으로 MappingJackson2HttpMessageConverter라는 구현체를 사용합니다.

📌 1. HttpMessageConverter란?

HttpMessageConverter는 Spring에서 제공하는 인터페이스로, 다음 두 가지 작업을 수행합니다:

  • 직렬화(Serialization): Java 객체 → HTTP 메시지 본문(JSON 등)
  • 역직렬화(Deserialization): HTTP 메시지 본문(JSON 등) → Java 객체

즉, 클라이언트와 서버 간 데이터 교환 시 자동으로 변환해주는 역할을 합니다.

✅ 주요 구현체

  • MappingJackson2HttpMessageConverter: JSON ↔ Java 객체 (Jackson 라이브러리 사용)
  • StringHttpMessageConverter: 문자열 ↔ Java String
  • ByteArrayHttpMessageConverter: 바이트 배열 ↔ Java byte[]
  • FormHttpMessageConverter: 폼 데이터 ↔ MultiValueMap
  • MappingJackson2XmlHttpMessageConverter: XML ↔ Java 객체

이 중 JSON 처리에 가장 많이 사용되는 것이 바로 MappingJackson2HttpMessageConverter입니다.

📌 2. Spring에서 JSON 응답 처리 방법

Spring에서 JSON 응답을 처리할 때는 일반적으로 두 가지 방법을 사용합니다:

✅ 2.1. @ResponseBody 애너테이션 사용

메서드에 @ResponseBody를 붙이면 메서드의 반환 값이 자동으로 HTTP 응답 본문에 바인딩됩니다.

@Controller
public class UserController {

    @GetMapping("/users/{id}")
    @ResponseBody
    public User getUser(@PathVariable Long id) {
        return new User(id, "John Doe", "john.doe@example.com");
    }
}

 이 코드가 실행되면, Spring은 내부적으로 등록된 MappingJackson2HttpMessageConverter를 통해 User 객체를 JSON으로 직렬화하여 클라이언트에게 전달합니다.

 

✅ 2.2. @RestController 애너테이션 사용 (더 간편한 방법)

@RestController는 @Controller + @ResponseBody가 결합된 형태입니다. 즉, 모든 메서드가 자동으로 JSON 응답을 반환합니다.

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "John Doe", "john.doe@example.com");
    }
}

 이 방식이 더 간결하고 자주 사용됩니다.

✅ JSON 응답 예시

위의 메서드를 호출하면 다음과 같은 JSON 응답이 클라이언트에게 전달됩니다:

{
    "id": 1,
    "name": "John Doe",
    "email": "john.doe@example.com"
}

📌 3. Message Converter 커스터마이징

기본적으로 Spring Boot는 자동으로 MappingJackson2HttpMessageConverter를 등록하여 JSON 처리를 지원합니다. 하지만 특정 요구사항에 따라 커스터마이징할 수 있습니다.

✅ 3.1. ObjectMapper 커스터마이징하기

JSON 직렬화/역직렬화 방식을 변경하려면 Jackson의 ObjectMapper를 설정하면 됩니다.

예시 코드:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        ObjectMapper objectMapper = new ObjectMapper();
        
        // JSON을 보기 좋게 포맷팅 (Pretty Print)
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        
        // 날짜 포맷 설정
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
        
        // 메시지 컨버터 생성 및 추가
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
        converters.add(converter);
    }
}

 

위 설정은 모든 JSON 응답을 보기 좋게 포맷팅하고 날짜 형식을 지정합니다.

✅ 3.2. 새로운 Message Converter 추가하기

필요 시 다른 유형의 Message Converter도 추가할 수 있습니다:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MappingJackson2HttpMessageConverter()); // 기본 JSON 컨버터 추가 예시
        converters.add(new StringHttpMessageConverter()); // 문자열 컨버터 추가 예시
    }
}
 

📌 4. ResponseEntity를 이용한 상태 코드와 함께 JSON 응답 처리하기

JSON 데이터와 함께 HTTP 상태 코드를 명확히 전달하려면 ResponseEntity를 사용합니다.

예시 코드:

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public ResponseEntity<?> getUser(@PathVariable Long id) {
        User user = findUserById(id);

        if (user == null) {
            Map<String, Object> error = Map.of(
                "status", "error",
                "message", "User not found",
                "error_code", 404
            );
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
        }

        return ResponseEntity.ok(user); // 상태 코드 200 OK와 함께 사용자 정보 반환
    }
}
 

✅ 성공적인 응답 예시 (200 OK):

{
    "id": 1,
    "name": "John Doe",
    "email": "john.doe@example.com"
}
 

✅ 오류 응답 예시 (404 Not Found):

{
    "status": "error",
    "message": "User not found",
    "error_code": 404
}
 

📌 🎯 요약 및 핵심 정리 🎯

개념 설명
HttpMessageConverter HTTP 요청/응답 본문 ↔ Java 객체 변환
MappingJackson2HttpMessageConverter JSON ↔ Java 객체 변환
@ResponseBody 메서드 반환 값을 자동으로 HTTP 응답 본문으로 변환
@RestController @Controller + @ResponseBody를 합친 편리한 애너테이션
ObjectMapper Jackson 라이브러리의 JSON 직렬화/역직렬화 설정
ResponseEntity 상태 코드와 함께 명확한 HTTP 응답 생성
 

Spring은 이러한 구조 덕분에 매우 간단하고 효율적으로 REST API에서 JSON 데이터를 처리할 수 있습니다! 😊


 WebMvcConfigurer와 HttpMessageConverter에 대한 추가적인 설명

📌 1. WebMvcConfigurer란?

 개념

  • WebMvcConfigurer는 Spring MVC를 커스터마이징하기 위한 인터페이스입니다.
  • 이 인터페이스는 Jackson 라이브러리와 직접적인 관련은 없으며, Spring MVC의 설정을 확장하거나 변경할 때 사용됩니다.
  • 여러 메서드를 제공하여 Spring MVC의 동작을 커스터마이징할 수 있습니다.

 주요 역할

  • 메시지 컨버터(HttpMessageConverter) 추가 또는 수정
  • CORS 설정
  • 인터셉터 추가
  • 뷰 리졸버 설정 등

📌 2. HttpMessageConverter란?

 개념

  • HttpMessageConverter는 HTTP 요청/응답 본문(body)을 Java 객체로 변환하거나, Java 객체를 HTTP 메시지 본문으로 변환하는 역할을 합니다.
  • Spring MVC는 요청과 응답 데이터를 처리할 때 내부적으로 이 컨버터를 사용합니다.

 기본 구현체

Spring Boot는 기본적으로 여러 종류의 HttpMessageConverter를 제공합니다:


구현체 역할
MappingJackson2HttpMessageConverter JSON ↔ Java 객체 변환 (Jackson 사용)
StringHttpMessageConverter 문자열 ↔ Java String 변환
ByteArrayHttpMessageConverter 바이트 배열 ↔ Java byte[] 변환
FormHttpMessageConverter 폼 데이터 ↔ MultiValueMap 변환
MappingJackson2XmlHttpMessageConverter XML ↔ Java 객체 변환 (Jackson 사용)

📌 3. WebMvcConfigurer와 HttpMessageConverter의 관계

Spring MVC에서 HttpMessageConverter는 요청과 응답 데이터를 처리하는 핵심 요소입니다.
WebMvcConfigurer를 사용하면 Spring MVC에 등록된 기본 메시지 컨버터를 수정하거나 새로운 메시지 컨버터를 추가할 수 있습니다.

📌 4. configureMessageConverters 메서드

 역할

  • Spring MVC에 등록된 메시지 컨버터 리스트(List<HttpMessageConverter<?>> converters)를 수정하거나 새로운 컨버터를 추가합니다.
  • 이 메서드를 오버라이딩하면 Spring MVC가 요청/응답 데이터를 처리할 때 사용할 메시지 컨버터를 커스터마이징할 수 있습니다.

 파라미터: List<HttpMessageConverter<?>> converters

  • Spring MVC가 사용하는 메시지 컨버터들의 리스트입니다.
  • 이 리스트에 새로운 메시지 컨버터를 추가하거나 기존 컨버터를 수정할 수 있습니다.

📌 5. 코드 동작 구조

예제 코드 분석:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // Jackson ObjectMapper 생성 및 설정
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT); // JSON 포맷팅 활성화
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); // 날짜 포맷 설정

        // MappingJackson2HttpMessageConverter 생성 및 추가
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
        converters.add(converter); // 커스터마이즈된 메시지 컨버터 추가
    }
}

동작 흐름:

  1. Spring Boot는 기본적으로 여러 HttpMessageConverter를 등록합니다.
  2. 개발자가 configureMessageConverters() 메서드를 오버라이딩하면 :
    • 기존 메시지 컨버터 리스트(converters)에 새로운 컨버터를 추가하거나 수정할 수 있습니다.
  3. Spring MVC는 요청/응답 데이터를 처리할 때 이 리스트에 등록된 메시지 컨버터를 순차적으로 확인하며 적합한 컨버터를 선택합니다.

📌 6. 실제 사용하는 방식

Spring MVC가 요청을 처리하거나 응답을 생성할 때, 등록된 메시지 컨버터 리스트를 순차적으로 확인합니다:

  1. 클라이언트가 JSON 데이터를 서버로 보냅니다.
    • 예: { "name": "John", "age": 30 }
  2. Spring은 등록된 메시지 컨버터 중 JSON 데이터를 처리할 수 있는 MappingJackson2HttpMessageConverter를 선택합니다.
  3. 이 컨버터는 JSON 데이터를 Java 객체로 역직렬화합니다.
    • 예: new User("John", 30)
  4. 서버가 Java 객체(User)를 클라이언트에게 응답으로 반환하려고 하면:
    • 다시 MappingJackson2HttpMessageConverter가 호출되어 Java 객체를 JSON으로 직렬화합니다.
    • 예: { "name": "John", "age": 30 }
클라이언트가 json으로 데이터 보냄 -> 서버에서 json을 객체로 변환 -> 서버에서 객체를 json으로 변환해서 클라이언트에게 넘김 ( 해당 과정에서 json <-> 객체는 모두 잭슨라이브러리에 의해 변환이 된다.)

📌 7. 커스터마이징한 메시지 컨버터의 장점

커스터마이징한 메시지 컨버터는 다음과 같은 상황에서 유용합니다:

  1. JSON 포맷 변경:
    • 기본 JSON 응답을 보기 좋게 포맷팅하거나 날짜 형식을 변경하고 싶을 때.
  2. 특정 데이터 형식 처리:
    • XML, YAML, CSV 등 다른 데이터 형식을 처리해야 할 때 새로운 메시지 컨버터 추가.
  3. 보안 요구사항:
    • 민감한 데이터를 제외하거나, 특정 필드를 암호화하여 응답해야 할 때.

📌 8. 전체 구조 요약

Spring MVC에서 요청/응답 데이터 처리 흐름:

  1. 클라이언트가 HTTP 요청을 보냄 (예: JSON 데이터).
  2. Spring MVC는 등록된 메시지 컨버터(List<HttpMessageConverter<?>>) 중 적합한 것을 선택함.
  3. 선택된 메시지 컨버터가 데이터를 직렬화/역직렬화하여 Controller로 전달.
  4. Controller가 데이터를 처리하고 응답을 반환함.
  5. 다시 적합한 메시지 컨버터가 호출되어 응답 데이터를 직렬화하여 클라이언트에게 전달.

📌 🎯 결론 및 요약 🎯

개념 역할
WebMvcConfigurer Spring MVC 설정 확장을 위한 인터페이스
HttpMessageConverter HTTP 요청/응답 ↔ Java 객체 간 변환
List<HttpMessageConverter<?>> Spring MVC에 등록된 모든 메시지 컨버터 리스트
configureMessageConverters() 기존 메시지 컨버터 수정 또는 새로운 메시지 컨버터 추가
MappingJackson2HttpMessageConverter JSON ↔ Java 객체 변환 (Jackson 라이브러리 사용)

 

 

Spring에서 REST API 통신 시, 이 구조는 데이터를 효율적으로 직렬화/역직렬화하고 클라이언트와 서버 간 원활한 통신을 가능하게 합니다! 😊


질문 : 잭슨 라이브러리가 제공하는 클래스는 ObjectMapper이고 스프링 부트에서 기본적으로 제공하는 HttpMessageConverter를 커스터마이징하기 위해서 사용되는 게 WebMvcConfigurer 라는거지??

답변 : 네, 정확합니다! 아래에서 **Jackson 라이브러리와 Spring Boot의 HttpMessageConverter 및 WebMvcConfigurer**에 대해 더 자세히 설명하겠습니다.

📌 1. Jackson 라이브러리가 제공하는 클래스: ObjectMapper

 개념

  • ObjectMapper는 Jackson 라이브러리의 핵심 클래스입니다.
  • JSON 데이터와 Java 객체 간 직렬화(Serialization) 및 역직렬화(Deserialization)를 수행합니다.
  • Spring Boot는 Jackson 라이브러리를 기본적으로 포함하고 있으며, 이를 통해 JSON 처리를 자동화합니다.

 주요 기능

  • JSON ↔ Java 객체 변환
  • JSON 데이터의 필드 추가/삭제/수정
  • 커스터마이징을 통해 날짜 포맷, 필드 제외 등 다양한 설정 가능

 사용 예시

import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonExample {
    public static void main(String[] args) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();

        // Java 객체 → JSON 직렬화
        User user = new User(1L, "John Doe", "john.doe@example.com");
        String json = objectMapper.writeValueAsString(user);
        System.out.println(json); // {"id":1,"name":"John Doe","email":"john.doe@example.com"}

        // JSON → Java 객체 역직렬화
        String jsonInput = "{\"id\":1,\"name\":\"John Doe\",\"email\":\"john.doe@example.com\"}";
        User deserializedUser = objectMapper.readValue(jsonInput, User.class);
        System.out.println(deserializedUser); // User{id=1, name='John Doe', email='john.doe@example.com'}
    }
}
 

📌 2. Spring Boot에서 기본 제공하는 HttpMessageConverter

 개념

  • HttpMessageConverter는 HTTP 요청/응답 본문을 Java 객체로 변환하거나, Java 객체를 HTTP 메시지 본문으로 변환하는 역할을 합니다.
  • Spring Boot는 기본적으로 여러 메시지 컨버터를 제공하며, 그중 가장 자주 사용되는 것이 **Jackson 기반의 MappingJackson2HttpMessageConverter**입니다.

 기본 동작

  • 클라이언트가 JSON 데이터를 서버로 보내면:
    • Spring은 등록된 메시지 컨버터 중 적합한 것을 선택하여 JSON 데이터를 Java 객체로 역직렬화합니다.
  • 서버가 Java 객체를 클라이언트에게 응답으로 반환하면:
    • Spring은 다시 메시지 컨버터를 사용하여 Java 객체를 JSON으로 직렬화합니다.

📌 3. 커스터마이징을 위한 WebMvcConfigurer

 개념

  • WebMvcConfigurer는 Spring MVC 설정을 확장하거나 변경하기 위해 제공되는 인터페이스입니다.
  • 이 인터페이스를 구현하면 기본 메시지 컨버터를 수정하거나 새로운 메시지 컨버터를 추가할 수 있습니다.

📌 4. configureMessageConverters 메서드

 역할

  • Spring MVC가 사용하는 기본 메시지 컨버터를 대체하거나 새로운 컨버터를 추가할 수 있습니다.
  • 이 메서드를 오버라이딩하면 기본 메시지 컨버터가 등록되지 않으므로 주의해야 합니다.

 파라미터: List<HttpMessageConverter<?>> converters

  • Spring MVC가 사용하는 모든 메시지 컨버터의 리스트입니다.
  • 이 리스트에 새로운 메시지 컨버터를 추가하거나 기존 컨버터를 수정할 수 있습니다.

📌 5. 코드 동작 구조

예제 코드 분석:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        ObjectMapper objectMapper = new ObjectMapper();
        
        // JSON 포맷팅 활성화 (보기 좋게 출력)
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        
        // 날짜 포맷 설정
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));

        // 커스터마이즈된 메시지 컨버터 추가
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
        converters.add(converter);
    }
}

동작 흐름:

  1. Spring Boot는 기본적으로 여러 메시지 컨버터를 등록합니다.
  2. 개발자가 configureMessageConverters() 메서드를 오버라이딩하면:
    • 기존 메시지 컨버터 리스트(converters)에 새로운 컨버터를 추가하거나 수정할 수 있습니다.
  3. Spring MVC는 요청/응답 데이터를 처리할 때 이 리스트에 등록된 메시지 컨버터를 순차적으로 확인하며 적합한 컨버터를 선택합니다.

📌 6. 실제 사용 시 동작 방식

Spring MVC에서 요청을 처리하거나 응답을 생성할 때 다음과 같은 흐름으로 동작합니다:

  1. 클라이언트가 HTTP 요청을 보냅니다 (예: JSON 데이터).
    • 예: { "name": "John", "age": 30 }
  2. Spring MVC는 등록된 메시지 컨버터 리스트(List<HttpMessageConverter<?>>) 중 적합한 것을 선택합니다.
    • 예: MappingJackson2HttpMessageConverter
  3. 선택된 메시지 컨버터가 데이터를 역직렬화하여 Controller로 전달합니다.
    • 예: new User("John", 30)
  4. Controller가 데이터를 처리하고 응답을 반환합니다.
  5. 다시 적합한 메시지 컨버터가 호출되어 응답 데이터를 직렬화하여 클라이언트에게 전달합니다.
    • 예: { "name": "John", "age": 30 }

📌 🎯 결론 및 요약 🎯

개념 역할
ObjectMapper Jackson 라이브러리의 핵심 클래스로 JSON ↔ Java 객체 변환 담당
HttpMessageConverter HTTP 요청/응답 ↔ Java 객체 변환
WebMvcConfigurer Spring MVC 설정 확장을 위한 인터페이스
configureMessageConverters 기존 메시지 컨버터 수정 또는 새로운 메시지 컨버터 추가
 

Spring Boot에서는 기본적으로 Jackson 기반의 JSON 처리를 제공하며, 필요에 따라 위 기능들을 활용해 커스터마이징할 수 있습니다. REST API 통신에서 이 구조는 데이터를 효율적으로 직렬화/역직렬화하고 클라이언트와 서버 간 원활한 통신을 가능하게 합니다! 😊

 

 


 질문 : 야 그러면 @RestController를 통해서 자바 객체가 JSON으로 변환되는데 그 과정에서 ObjectMapper가 직렬화를 해주는거임??

답변 : 네, 정확합니다! Spring Boot에서 @RestController를 사용하면 자바 객체가 JSON으로 변환되는데, 그 과정에서 **Jackson의 ObjectMapper**가 직렬화를 담당합니다. 아래에서 그 동작 과정을 자세히 설명하겠습니다.

 

📌 1. @RestController와 JSON 변환 과정

 동작 흐름

  1. 클라이언트가 HTTP 요청을 보냅니다.
  2. @RestController가 붙은 메서드가 호출되어 Java 객체를 반환합니다.
  3. Spring MVC는 반환된 Java 객체를 HTTP 응답 본문(body)에 넣기 위해 **메시지 컨버터(HttpMessageConverter)**를 사용합니다.
  4. **Jackson의 MappingJackson2HttpMessageConverter**가 선택됩니다.
  5. 이 컨버터는 내부적으로 Jackson 라이브러리의 **ObjectMapper**를 사용하여 Java 객체를 JSON으로 직렬화합니다.
  6. 클라이언트에게 JSON 응답이 전송됩니다.

📌 2. ObjectMapper의 역할

 ObjectMapper란?

  • Jackson 라이브러리의 핵심 클래스입니다.
  • 자바 객체를 JSON으로 변환(직렬화)하거나 JSON을 자바 객체로 변환(역직렬화)하는 역할을 합니다.

 직렬화 과정

  • 자바 객체의 필드와 값을 JSON 형식으로 변환합니다.
  • 예를 들어:
User user = new User(1L, "John Doe", "john.doe@example.com");
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(user);
System.out.println(json); // {"id":1,"name":"John Doe","email":"john.doe@example.com"}

📌 3. @RestController와 ObjectMapper의 연관성

Spring Boot는 기본적으로 Jackson 라이브러리를 사용하여 JSON 처리를 자동화합니다.
이 과정에서 MappingJackson2HttpMessageConverter가 내부적으로 Jackson의 ObjectMapper를 사용합니다.

✅ 동작 구조:

  1. 클라이언트가 요청을 보냄.
  2. @RestController 메서드가 Java 객체를 반환함:
  3. Spring MVC는 반환된 User 객체를 HTTP 응답 본문에 넣기 위해 메시지 컨버터를 찾음.
  4. MappingJackson2HttpMessageConverter가 선택됨.
  5. 이 컨버터는 내부적으로 Jackson의 ObjectMapper를 사용하여 User 객체를 JSON으로 직렬화함:
// 1번
@RestController
public class UserController {
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "John Doe", "john.doe@example.com");
    }
}
// 5번
{
    "id": 1,
    "name": "John Doe",
    "email": "john.doe@example.com"
}

📌 4. 커스터마이징 가능성

Spring Boot는 기본적으로 제공하는 ObjectMapper 설정을 커스터마이징할 수 있습니다.

✅ 커스터마이징 예시:

@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        
        // 보기 좋게 포맷팅 (Pretty Print)
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        
        // 날짜 포맷 설정
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
        
        return mapper;
    }
}
 

위 설정을 추가하면 모든 JSON 응답이 보기 좋게 포맷팅되고 날짜 형식도 지정됩니다.

📌 5. 전체 동작 요약

단계역할
1️⃣ 클라이언트 요청 클라이언트가 HTTP 요청을 보냄
2️⃣ Controller 처리 @RestController 메서드에서 Java 객체 반환
3️⃣ 메시지 컨버터 선택 Spring MVC가 적합한 메시지 컨버터(MappingJackson2HttpMessageConverter) 선택
4️⃣ ObjectMapper 호출 메시지 컨버터가 내부적으로 Jackson의 ObjectMapper 호출
5️⃣ 직렬화 수행 ObjectMapper가 Java 객체 → JSON 변환
6️⃣ 응답 전송 변환된 JSON 데이터를 클라이언트에게 응답으로 전송
 

📌 🎯 결론

  • Spring Boot에서 @RestController는 자바 객체를 JSON으로 변환하는 역할을 합니다.
  • 이 과정에서 Spring MVC는 내부적으로 HttpMessageConverter를 사용하며, 기본적으로 MappingJackson2HttpMessageConverter가 선택됩니다.
  • 이 컨버터는 Jackson 라이브러리의 ObjectMapper를 이용해 직렬화를 수행합니다.
  • 따라서, Spring Boot에서 자바 객체 → JSON 변환은 결국 ObjectMapper에 의해 처리된다고 볼 수 있습니다.

REST API 통신에서 이 구조는 데이터를 효율적으로 직렬화하고 클라이언트와 서버 간 원활한 데이터 교환을 가능하게 합니다! 😊


질문 : 기존에 HttpMessageConverter가 @RestController 붙은 메서드에 객체를 json으로 반환하잖아?? 그러면 WebMvcConfigurer로 재정의한 매퍼를 List<HttpMessageConverter<?>> converters에 넣어주면 이제부터 @RestController 붙은 메서드는 재정의된 매퍼로 json 데이터를 반환해주는거임?

답변 : 네, 정확히 이해하셨습니다. 질문을 다시 명확히 정리하면 다음과 같습니다.

정답은 "네, 맞습니다." 입니다.

📌 정확한 동작 원리 (자세한 설명)

Spring MVC에서 @RestController가 붙은 메서드가 객체를 반환하면, 다음과 같은 순서로 JSON 변환이 이루어집니다:

✅ 기본 동작 흐름 (커스터마이징 전)

  1. @RestController 메서드가 Java 객체를 반환합니다.
  2. Spring MVC는 이 객체를 HTTP 응답 본문(body)에 넣기 위해 등록된 메시지 컨버터(HttpMessageConverter) 목록을 순서대로 확인합니다.
  3. 기본적으로 Spring Boot는 여러 메시지 컨버터를 자동으로 등록해두며, JSON 처리는 주로 **MappingJackson2HttpMessageConverter**가 담당합니다.
  4. 이 컨버터는 내부적으로 Jackson의 **기본 ObjectMapper**를 사용하여 Java 객체 → JSON 변환(직렬화)을 수행합니다.

✅ WebMvcConfigurer로 커스터마이징한 경우의 동작 흐름

개발자가 직접 WebMvcConfigurer 인터페이스의 configureMessageConverters() 메서드를 오버라이딩하여 메시지 컨버터 목록을 재정의하면, 다음과 같이 동작합니다:

  • 중요: configureMessageConverters() 메서드를 오버라이딩하면 기존에 Spring Boot가 자동으로 등록했던 기본 메시지 컨버터들이 모두 제거됩니다.
  • 즉, 이때부터는 개발자가 직접 등록한 컨버터만 사용됩니다.

예시 코드:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        ObjectMapper customObjectMapper = new ObjectMapper();
        customObjectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        customObjectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));

        // 커스터마이징된 ObjectMapper로 메시지 컨버터 생성
        MappingJackson2HttpMessageConverter customConverter =
                new MappingJackson2HttpMessageConverter(customObjectMapper);

        // 직접 만든 컨버터를 리스트에 추가 (기존것들은 제거됨)
        converters.add(customConverter);
    }
}

 

위 코드를 적용하면:

  1. Spring MVC는 이제부터 개발자가 직접 추가한 메시지 컨버터만 사용합니다.
  2. 따라서 모든 JSON 변환 작업에서 개발자가 설정한 커스터마이징된 ObjectMapper가 적용됩니다.
  3. 이후부터는 모든 @RestController 메서드가 반환하는 객체는 이 커스터마이징된 컨버터(customConverter)를 통해 JSON으로 변환됩니다.

📌 실제 예시로 확인하기

다음과 같은 Controller 코드가 있다고 가정해봅시다:

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "John Doe", "john.doe@example.com", null);
    }
}
  • 위의 WebMvcConfigurer 설정을 적용하기 전에는 기본적인 JSON 형식으로 출력됩니다(들여쓰기 없음).
  • 위의 WebMvcConfigurer 설정을 적용한 이후에는 들여쓰기(Pretty Print)가 적용되고 날짜 포맷 등도 변경된 형태로 출력됩니다.

즉, WebMvcConfigurer로 등록한 커스터마이징된 메시지 컨버터가 실제로 동작하며, 모든 @RestController 응답에 영향을 미칩니다.

📌 주의사항 (중요!)

  • 만약 기존의 기본 메시지 컨버터들을 유지하면서 추가적인 메시지 컨버터만 추가하고 싶다면:
    • configureMessageConverters() 대신에 extendMessageConverters() 메서드를 오버라이딩해야 합니다.

예시:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        ObjectMapper customObjectMapper = new ObjectMapper();
        customObjectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        customObjectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));

        MappingJackson2HttpMessageConverter customConverter =
                new MappingJackson2HttpMessageConverter(customObjectMapper);

        // 기존 컨버터 리스트에 추가 (기존 것 유지)
        converters.add(0, customConverter); // 우선순위를 높이고 싶다면 앞쪽에 추가
    }
}
  • 이렇게 하면 기존의 기본 컨버터들이 유지되면서 내가 만든 커스텀 컨버터도 추가됩니다.

📌 🎯 결론 및 최종 정리 🎯

질문답변
WebMvcConfigurer로 재정의한 매퍼(ObjectMapper)를 사용해 JSON 데이터를 반환하는 게 맞나요? ✅ 네, 맞습니다!
configureMessageConverters() 사용 시 기존 기본 컨버터는 어떻게 되나요? ⚠️ 기존 기본 컨버터들은 제거되고 내가 추가한 것만 사용됩니다.
기존 컨버터 유지하면서 추가만 하려면? ✅ extendMessageConverters() 메서드를 사용하세요!
 

즉, 질문하신 내용은 정확히 이해하신 것이며,
실제로 REST API 개발 시 자주 사용하는 중요한 개념입니다! 😊


📌 1. HttpMessageConverter

 개념

HttpMessageConverter는 Spring에서 HTTP 요청과 응답의 본문(body)을 Java 객체로 변환하거나 (직렬화), Java 객체를 HTTP 메시지 본문으로 변환하는 역할을 합니다. (역직렬화)

  • 클라이언트 ↔ 서버 간 데이터 교환 시 자동 변환
  • 다양한 형식(JSON, XML 등)을 처리 가능

📍 주요 구현체: MappingJackson2HttpMessageConverter

  • JSON ↔ Java 객체 변환 담당
  • 내부적으로 Jackson 라이브러리를 사용하여 직렬화(Serialization), 역직렬화(Deserialization) 수행

📌 2. @ResponseBody 애너테이션

Spring MVC에서 메서드 반환 값을 HTTP 응답 본문에 자동으로 매핑합니다.

  • 메서드의 리턴 값을 HTTP 응답 본문(body)에 직접 바인딩
  • 기본적으로 JSON 형태로 변환됨 (Jackson 라이브러리 사용)

📍 사용 예시:

@Controller
public class UserController {

    @GetMapping("/users/{id}")
    @ResponseBody
    public User getUser(@PathVariable Long id) {
        return new User(id, "John Doe", "john.doe@example.com");
    }
}
 
  • 위 코드 실행 시 User 객체가 자동으로 JSON으로 변환되어 클라이언트에게 전달됩니다.

📌 3. @RestController 애너테이션

@RestController는 @Controller와 @ResponseBody를 결합한 편리한 애너테이션입니다.

📍 사용법 비교:

// 기존 방식 (@Controller + @ResponseBody)
@Controller
public class OldUserController {

    @GetMapping("/users/{id}")
    @ResponseBody
    public User getUser(@PathVariable Long id) {
        return new User(id, "John Doe", "john.doe@example.com");
    }
}

// @RestController 방식 (권장)
@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "John Doe", "john.doe@example.com");
    }
}
 
  • @RestController 사용 시 더 간결하고 편리합니다.
  • REST API 구현 시 일반적으로 이 방식을 사용합니다.

📌 4. ObjectMapper 클래스

Jackson 라이브러리에서 JSON 데이터와 Java 객체 간 직렬화(Serialization)/역직렬화(Deserialization)를 처리하는 핵심 클래스입니다.

📍 주요 기능:

  • Java 객체 → JSON 직렬화 (serialization)
  • JSON → Java 객체 역직렬화 (deserialization)
  • 날짜 포맷 설정, 필드 제외 등 다양한 커스터마이징 가능

📍 커스터마이징 예시 코드(Spring Boot):

@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        
        // 보기 좋게 포맷팅 설정
        mapper.enable(SerializationFeature.INDENT_OUTPUT);

        // 날짜 포맷 설정
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));

        return mapper;
    }
}
 

위와 같이 설정하면 모든 JSON 응답이 보기 좋게 포맷팅되고 날짜 형식도 일관되게 설정됩니다.

📌 4. ResponseEntity 클래스

ResponseEntity는 HTTP 상태 코드, 헤더, 본문 데이터를 함께 전달할 수 있는 Spring의 유용한 클래스입니다.

📍 주요 용도:

  • 상태 코드 명확히 지정 가능 (200 OK, 404 Not Found 등)
  • 응답 본문(body)과 상태 코드를 함께 반환 가능

📍 사용 예시 코드:

@RestController
public class UserController {

    @GetMapping("/users/{id}")
    public ResponseEntity<?> getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        
        if(user == null){
            Map<String, Object> error = Map.of(
                "status", "error",
                "message", "User not found",
                "error_code", 404
            );
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
        }

        return ResponseEntity.ok(user); //200 OK 상태코드와 함께 사용자 정보 반환
    }
}

📍 자주 사용하는 메서드 정리:

메서드 설명 예시
ok() 200 OK 상태 코드 반환 return ResponseEntity.ok(user);
created() 201 Created 상태 코드 반환 return ResponseEntity.created(uri).body(user);
noContent() 204 No Content 반환 (본문 없음) return ResponseEntity.noContent().build();
badRequest() 400 Bad Request 반환 return ResponseEntity.badRequest().body(error);
notFound() 404 Not Found 반환 return ResponseEntity.notFound().build();
 

📌 정리 및 요약

REST API 구현 시 다음과 같은 개념과 클래스는 필수적으로 사용됩니다.

 

개념/클래스 역할 및 설명
HttpMessageConverter (MappingJackson2HttpMessageConverter) HTTP 요청/응답 ↔ Java 객체 간 변환(JSON 처리 담당)
@ResponseBody 메서드 리턴 값을 HTTP 응답 본문에 자동 매핑(JSON 형태)
@RestController @Controller + @ResponseBody 결합형 애너테이션
ObjectMapper Jackson 라이브러리의 JSON 직렬화 및 역직렬화 담당
ResponseEntity HTTP 상태 코드와 함께 명확한 응답 생성
 

이 다섯 가지 요소를 정확히 이해하고 활용하면 REST API를 효율적이고 명확하게 설계하고 구현할 수 있습니다. 실제로 Spring Boot에서는 이 기능들을 기본적으로 제공하므로 별도의 복잡한 설정 없이도 쉽게 사용할 수 있습니다! 😊