[SpringBoot] Object Mapper

허훈·2023년 12월 27일
0

spring-boot

목록 보기
5/6
post-thumbnail

✅ Object Mapper

우리가 지겹도록 반복한 과정이 있다.

클라이언트에서 보낸 Json 데이터를 DTO 객체로 받으면, Spring에서 알아서 Json의 Key값과 DTO 객체의 멤버변수를 매칭해서 Value값을 DTO 객체에 자동으로 대입해주었는데, 그 과정을 바로 SpringBoot의 Object Mapper 클래스가 해준다. Object Mapper는 Controller가 받아온 텍스트 형태로 넘어온 Json 데이터를 객체(Object)로 바꿔주고, Controller의 메서드가 객체(Object)를 리턴하면, 즉 클라이언트로 응답 메시지를 보내기 전에 다시 객체를 텍스트 형태의 Json 데이터로 변환해준다.

Json → Object의 과정을 역직렬화(Deserialization),
Object → Json의 과정을 직렬화(Serialization)라고 한다.

우리가 SpringBoot 프로젝트를 만들기 위해서 가장 먼저 spring-boot-starter-web 라이브러리에 대한 의존성 주입을 해야한다. 아마 프로젝트를 만들 때, starter-web은 Lombok 라이브러리와 함께 가장 많이 주입되는 라이브러리가 아닐까 싶다.
(의존성 주입하는 방법은 굳이 설명하지 않겠다.)

spring-boot-starter-web 아래, jackson 라이브러리가 있고, jackson-databind 라이브러리 안에 Object Mapper 클래스가 존재한다. SpringBoot는 그 jackson의 Object Mapper를 '자동'으로 실행하여 Json과 Object를 상호전환할 수 있게 해주는 것이다. 하지만, 개발자가 Object Mapper를 통해 특별한 작업을 해야하는 경우, (예를 들면 Json 문자열 형식을 내가 원하는 방식으로 수정하고 싶다거나...) Object Mapper 객체를 직접 생성해서 작업을 진행할 수 있다.

우리는 Object Mapper 객체를 직접 만들어보고, 어떻게 Json을 Object로, Object를 Json으로 변환해주는지 테스트 코드를 작성해보고자 한다.

@SpringBootTest
class SpringResponseApplicationTests {
    @Test
    void contextLoads() { }
}

다음과 같이 텍스트 코드 작성을 준비하자.

참고로 contextLoads 메서드는, SpringBoot에서 애플리케이션이 성공적으로 작동하는지 확인하는 메서드로, SpringBoot 프로젝트를 생성할 때 ...Test 클래스 아래에 자동으로 만들어지는 테스트용 메서드이다. 당연히 테스트 메서드이므로 특정 작업을 위한 용도가 아닌, 단순 검증을 위한 메서드이므로, 실제 프로젝트에는 전혀 영향을 주지 않는다.


✅ Json → Object

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString()
public class Member {
    private String memberName;
    private int memberAge;
    @JsonProperty("member_phone")
    private String memberPhone;
}

@Test
void contextLoads() throws JsonProcessingException {
    ObjectMapper om = new ObjectMapper();

    // object -> text
    Member member = new Member("John", 25, "010-1234-5678");
    String text = om.writeValueAsString(member);
    System.out.println(text);
}

자 우선, ObjectMapper 클래스의 객체(om)를 만든다.

3개의 멤버 변수를 가지는 Member 클래스를 선언하고, 오버로딩된 생성자를 사용하여 member 객체를 하나 만들어준다. 그리고, ObjectMapper의 writeValueAsString 메서드에 객체를 인수로 넘기면, 해당 객체를 문자열(Json)로 변환할 수 있다.

text를 출력하니, 객체가 Json 문자열로 변환된 것을 확인할 수 있다.

이 때, DTO 클래스에는 모든 멤버 변수에 대한 getter 메서드가 반드시 추가되어 있어야 하는데, 우리는 Lombok 라이브러리의 @Getter 어노테이션을 이미 선언해놓았기 때문에 정상적으로 코드가 작동한다.


✅ Text → Object


@Test
void contextLoads() throws JsonProcessingException {
    ObjectMapper om = new ObjectMapper();

	// object -> text
    Member member = new Member("John", 25, "010-1234-5678");
    String text = om.writeValueAsString(member);
    System.out.println(text);
    
    // text -> object
    Member convertedMember = om.readValue(text, Member.class);
    System.out.println(convertedMember);
}

Member 클래스는 위와 동일하기 때문에 생략했다.

ObjectMapper의 readValue 메서드에 Json 데이터와, 변환하고자하는 객체의 자료형(.class)를 인수로 대입하면 문자열 형식의 Json 데이터가 해당 객체로 자동으로 변환된다.

정상적으로 Object 변환이 완료된 것을 확인할 수 있다. 일전에도 많이 얘기했지만, memberPhone 멤버변수 위에 @JsonProperty 어노테이션을 선언했기 때문에, Json의 snake_case가 camelCase로 잘 변환된 것까지 확인할 수 있다.

이 때, DTO 클래스에는 default 생성자가 반드시 선언되어 있어야 하는데, 우리는 Lombok 라이브러리의 @NoArgsConstructor를 이미 선언해놓았기 때문에 큰 문제가 없다.


0개의 댓글

관련 채용 정보