Spring의 HttpMessageConverter는 HTTP 요청과 응답의 본문(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); // 커스터마이즈된 메시지 컨버터 추가
}
}
동작 흐름:
- Spring Boot는 기본적으로 여러 HttpMessageConverter를 등록합니다.
- 개발자가 configureMessageConverters() 메서드를 오버라이딩하면 :
- 기존 메시지 컨버터 리스트(converters)에 새로운 컨버터를 추가하거나 수정할 수 있습니다.
- Spring MVC는 요청/응답 데이터를 처리할 때 이 리스트에 등록된 메시지 컨버터를 순차적으로 확인하며 적합한 컨버터를 선택합니다.
📌 6. 실제 사용하는 방식
Spring MVC가 요청을 처리하거나 응답을 생성할 때, 등록된 메시지 컨버터 리스트를 순차적으로 확인합니다:
- 클라이언트가 JSON 데이터를 서버로 보냅니다.
- 예: { "name": "John", "age": 30 }
- Spring은 등록된 메시지 컨버터 중 JSON 데이터를 처리할 수 있는 MappingJackson2HttpMessageConverter를 선택합니다.
- 이 컨버터는 JSON 데이터를 Java 객체로 역직렬화합니다.
- 예: new User("John", 30)
- 서버가 Java 객체(User)를 클라이언트에게 응답으로 반환하려고 하면:
- 다시 MappingJackson2HttpMessageConverter가 호출되어 Java 객체를 JSON으로 직렬화합니다.
- 예: { "name": "John", "age": 30 }
클라이언트가 json으로 데이터 보냄 -> 서버에서 json을 객체로 변환 -> 서버에서 객체를 json으로 변환해서 클라이언트에게 넘김 ( 해당 과정에서 json <-> 객체는 모두 잭슨라이브러리에 의해 변환이 된다.)
📌 7. 커스터마이징한 메시지 컨버터의 장점
커스터마이징한 메시지 컨버터는 다음과 같은 상황에서 유용합니다:
- JSON 포맷 변경:
- 기본 JSON 응답을 보기 좋게 포맷팅하거나 날짜 형식을 변경하고 싶을 때.
- 특정 데이터 형식 처리:
- XML, YAML, CSV 등 다른 데이터 형식을 처리해야 할 때 새로운 메시지 컨버터 추가.
- 보안 요구사항:
- 민감한 데이터를 제외하거나, 특정 필드를 암호화하여 응답해야 할 때.
📌 8. 전체 구조 요약
Spring MVC에서 요청/응답 데이터 처리 흐름:
- 클라이언트가 HTTP 요청을 보냄 (예: JSON 데이터).
- Spring MVC는 등록된 메시지 컨버터(List<HttpMessageConverter<?>>) 중 적합한 것을 선택함.
- 선택된 메시지 컨버터가 데이터를 직렬화/역직렬화하여 Controller로 전달.
- Controller가 데이터를 처리하고 응답을 반환함.
- 다시 적합한 메시지 컨버터가 호출되어 응답 데이터를 직렬화하여 클라이언트에게 전달.
📌 🎯 결론 및 요약 🎯
| 개념 | 역할 |
| 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);
}
}
동작 흐름:
- Spring Boot는 기본적으로 여러 메시지 컨버터를 등록합니다.
- 개발자가 configureMessageConverters() 메서드를 오버라이딩하면:
- 기존 메시지 컨버터 리스트(converters)에 새로운 컨버터를 추가하거나 수정할 수 있습니다.
- Spring MVC는 요청/응답 데이터를 처리할 때 이 리스트에 등록된 메시지 컨버터를 순차적으로 확인하며 적합한 컨버터를 선택합니다.
📌 6. 실제 사용 시 동작 방식
Spring MVC에서 요청을 처리하거나 응답을 생성할 때 다음과 같은 흐름으로 동작합니다:
- 클라이언트가 HTTP 요청을 보냅니다 (예: JSON 데이터).
- 예: { "name": "John", "age": 30 }
- Spring MVC는 등록된 메시지 컨버터 리스트(List<HttpMessageConverter<?>>) 중 적합한 것을 선택합니다.
- 예: MappingJackson2HttpMessageConverter
- 선택된 메시지 컨버터가 데이터를 역직렬화하여 Controller로 전달합니다.
- 예: new User("John", 30)
- Controller가 데이터를 처리하고 응답을 반환합니다.
- 다시 적합한 메시지 컨버터가 호출되어 응답 데이터를 직렬화하여 클라이언트에게 전달합니다.
- 예: { "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 변환 과정
✅ 동작 흐름
- 클라이언트가 HTTP 요청을 보냅니다.
- @RestController가 붙은 메서드가 호출되어 Java 객체를 반환합니다.
- Spring MVC는 반환된 Java 객체를 HTTP 응답 본문(body)에 넣기 위해 **메시지 컨버터(HttpMessageConverter)**를 사용합니다.
- **Jackson의 MappingJackson2HttpMessageConverter**가 선택됩니다.
- 이 컨버터는 내부적으로 Jackson 라이브러리의 **ObjectMapper**를 사용하여 Java 객체를 JSON으로 직렬화합니다.
- 클라이언트에게 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를 사용합니다.
✅ 동작 구조:
- 클라이언트가 요청을 보냄.
- @RestController 메서드가 Java 객체를 반환함:
- Spring MVC는 반환된 User 객체를 HTTP 응답 본문에 넣기 위해 메시지 컨버터를 찾음.
- MappingJackson2HttpMessageConverter가 선택됨.
- 이 컨버터는 내부적으로 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 변환이 이루어집니다:
✅ 기본 동작 흐름 (커스터마이징 전)
- @RestController 메서드가 Java 객체를 반환합니다.
- Spring MVC는 이 객체를 HTTP 응답 본문(body)에 넣기 위해 등록된 메시지 컨버터(HttpMessageConverter) 목록을 순서대로 확인합니다.
- 기본적으로 Spring Boot는 여러 메시지 컨버터를 자동으로 등록해두며, JSON 처리는 주로 **MappingJackson2HttpMessageConverter**가 담당합니다.
- 이 컨버터는 내부적으로 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);
}
}
위 코드를 적용하면:
- Spring MVC는 이제부터 개발자가 직접 추가한 메시지 컨버터만 사용합니다.
- 따라서 모든 JSON 변환 작업에서 개발자가 설정한 커스터마이징된 ObjectMapper가 적용됩니다.
- 이후부터는 모든 @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에서는 이 기능들을 기본적으로 제공하므로 별도의 복잡한 설정 없이도 쉽게 사용할 수 있습니다! 😊
'Spring > 10. rest-api' 카테고리의 다른 글
| @PathVariable / @RequesteBody / @RequestParam (0) | 2025.03.16 |
|---|---|
| REST API 예제 (0) | 2025.03.14 |
| REST API (0) | 2025.03.14 |
| rest api 와 서버 사이드 렌더링 / 클라이언트 사이드 렌더링과의 연관성 (0) | 2025.03.08 |
| REST API의 개념 (2) | 2025.03.08 |