스프링 컨트롤러 객체 매핑

2024. 3. 19. 15:27카테고리 없음

오브젝트 매퍼 원리

http 요청(json)을 메세지 컨버터가 자바 객체로 만들때 오브젝트 매핑을 이용하여 직렬화한다.

 

메시지 컨버터의 경우 HTTP 요청이나 응답의 본문(body)에 포함된 데이터를 읽는 역할을 맡는다.

주로 바디 형식에 따라 어떠한 오브젝트 매퍼를 선택할지 결정하고 이를 이용해 요청을 자바 객체로 변환한다.

이때 바디를 자바 객체로 바꾸는 역할을 하는 것이 오브젝트 매퍼이다.

 

아래의 블로그는 json string을 직접 자바객체로 만드는 예시 코드를 보인다.

 

[Java] ObjectMapper를 이용하여 JSON 파싱하기

Jackson 라이브러리의 ObjectMapper 클래스를 이용하여 JSON을 파싱해봅시다.

velog.io

 

다음 블로그는 오브젝트 매핑에 어떠한 설정을 할 수 있는지 소개한다.

 

ObjectMapper

1. serialize/deserialize 이슈 EDA 기반에서 메세지들의 serialize/deserialize 는 특히 더 주의해야한다. 시스템들이 분산 되어 있기 때문이다. 예를 들어 아래 그림 System1 에서 serialize 하고 메세지를 발행하

yangbongsoo.tistory.com

 

오브젝트 매핑 전역 설정.

날짜 json 직렬화 형식, 스네이프 케이스, 없는 필드 무시 등 새로운 오브젝트 매퍼를 생성하여 직접 사용할 수 있다.

이 경우 2가지 옵션이 있다. 1번째는 직접 커스텀한 오브젝트 매퍼를 빈으로 등록하는 것이고 2번째는 메세지 컨버터에서 사용하는 기본 오브젝트 매퍼의 설정을 이어받은 후 추가로 설정하는 방법이 있다.

 

해당 블로그는 직접 serializer를 만들고 이를 오브젝트 매퍼에 등록하는 방법을 보여주고 있다.

 

jackson custom serializer, deserializer 만들기

1. JacksonAjax 통신을 할때는 Response Body에 데이터만 담아서 클라이언트로 전송하게된다. 이때 가장 많이 사용하는 포맷은 json 형태일텐데 자바 객체를 json 형태로 변환해주는 여러 라이브러리중 하

multifrontgarden.tistory.com

메세지 컨버터는 바디를 읽고 적절한 오브젝트 매퍼를 매칭시킨다고 했다.

json에 있는 필드명과 우리가 매핑하려는 객체의 필드명과 일치하면 이를 객체에 옮겨 담아야한다.

이때 매핑하려는 객체가 또 다른 객체를 참조한다면? json depth가 깊어지게 된다.

모든 필드가 아니라 특정 필드만을 json에 담기위해 serializer를 생성하여 우리가 원하는 대로 객체를 매핑 시킬 수 있다.

 

해당 블로그는 젝슨 라이브러리(메세지 컨버터)가 사용하는 오브젝트 매퍼에 추가 설정하는 방법을 다룬다.

 

spring boot 에서 ObjectMapper 확장하기

spring-boot-starter-web 을 이용해 웹서버 애플리케이션을 만들고 있다면 json 에 대한 핸들링은 jackson 을 이용하게 된다. 물론 jackson 외 다른 라이브러리를 이용하고 싶다면 변경할 수 있다. jackson 에서

multifrontgarden.tistory.com

 

import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

@Configuration
public class ObjectMapperCustomizerConfig {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer objectMapperCustomizer() {
        return builder -> {
            // JDK 8 모듈 및 Java Time 모듈 추가
            builder.modules(new Jdk8Module(), new JavaTimeModule());
            // 날짜를 타임스탬프로 쓰지 않고 ISO-8601 형식으로 직렬화하도록 설정
            builder.featuresToDisable(
                SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
                SerializationFeature.FAIL_ON_EMPTY_BEANS
            );
            // 알 수 없는 속성이 있을 때 예외를 발생시키지 않고 무시하도록 설정
            builder.featuresToEnable(
                DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
            );
            // 속성 네이밍 전략을 스네이크 케이스로 설정
            builder.propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
        };
    }
}

 

내용을 종합하여 예제 코드를 만들었다.