ObjectMapper란?

jaeygun·2022년 7월 31일
0

웹개발을 하다보면 json을 object로 바꿔주어야 하기도 하고 object형태를 json으로 바꿔주어야 하기도 한다. 이럴때를 위해 유용하게 사용할 수 있는 objectMapper를 소개하려고 한다.
(자바버전은 11을 사용했다)

테스트를 위해서 간단하게 Person이라는 DTO를 만들고 진행을 하였다.

public class Person {

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    } 

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

}

일단 테스트를 위해 간단하게 필드 선언과 생성자와 toString메소드만 만들고 진행을 하였다.

@Test
    void contextLoads() throws JsonProcessingException {

        var objectMapper = new ObjectMapper();
        var person = new Person("제윤건", 25);

        // object > text(json)
        var text = objectMapper.writeValueAsString(person);
        System.out.println(text);
    }

objectMapper와 person객체를 만들고 writeValuesAsString()메소드를 이용해 변환 후 실행해 보았다.

No serializer found for class com.example.hello.vo.Person and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.example.hello.vo.Person and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
	at app//com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
	at app//com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1300)
	at app//com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
	at app//com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:46)
	at app//com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:29)
	at app//com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
	at app//com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)

실행결과는 위와 같은 에러가 나오는데 에러내용을 살펴보면 no properties discovered to create BeanSerializer와 같은 에러 문구를 볼 수 있다.
그래서 DTO에 getter를 추가하고 다시 진행해 보았다.

실행결과 아래와 같은 json타입으로 나온 결과값을 확인 할 수 있을것이다.
이를 통해서 obejct형태에서 json으로 변환하기 위한 writeValuesAsString() 메소드는 인스턴스의 get method를 활용한다는 것을 알 수 있다.

{"name":"제윤건","age":25}

이번에는 json의 형태를 object의 형태로 바꿔보도록 하자
위의 메소드를 통해서 지금 text라는 인스턴스는 json의 형으로 바뀌어 있는 상태이다. 그 상태로

    @Test
    void contextLoads() throws JsonProcessingException {

        var objectMapper = new ObjectMapper();
        var person = new Person("제윤건", 25);

        // object > text(json)
        var text = objectMapper.writeValueAsString(person);
        System.out.println(text);

        // text(json) > object
        var json = objectMapper.readValue(text, Person.class);
        System.out.println(json);
    }

이와 같이 테스트 코드를 작성하고 실행을 해보았을 때

{"name":"제윤건","age":25}

Cannot construct instance of `com.example.hello.vo.Person` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"name":"제윤건","age":25}"; line: 1, column: 2]
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.hello.vo.Person` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (String)"{"name":"제윤건","age":25}"; line: 1, column: 2]
	at app//com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
	at app//com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1904)
	at app//com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
	at app//com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1349)
	at app//com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1415)
	at app//com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:351)
	at app//com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:184)
	at app//com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
	at app//com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)

첫 번째 실행결과인 text는 정상동작을 하였지만 두번째 실행은 되지 않았다.

no Creators, like default constructor, exist

에러의 내용을 보면 이와같은 default constructor와 같은 creator가 없다고 나오는데 그래서 default생성자를 추가 한 후 다시 실행 해보았다.

{"name":"제윤건","age":25}
Person{name='제윤건', age=25}

이번에는 두 실행결과 모두 정상적으로 나온 것을 확인할 수 있다.

0개의 댓글