언어(Language)/Java

[Java] 자바 JSON 라이브러리 Jackson - ObjectMapper 사용법

잇트루 2023. 5. 9. 00:25
반응형

Jackson

Jackson 라이브러리는 자바에서 데이터 처리를 위한 라이브러리로 xml, yml, properties, csv, json 등 다양한 형식의 데이터 처리가 가능한 라이브러리다. 일반적으로 자바용 JSON 라이브러리로 알려져 있다.

  • Jackson 라이브러리는 스트림 방식으로 속도가 빠르고 유연하며, 어노테이션 방식으로 메타 데이터를 기술할 수 있다.
  • ObjectMapper를 통해 Java 객체와 JSON 형식의 문자열 간의 직렬화(Serialization), 역직렬화(Deserialization)가 가능하다.
  • 스프링 부트에서는 Jackson 라이브러리가 기본적으로 추가되어 별도의 의존성 추가 없이 사용할 수 있다.

 

 

Jackson 라이브러리 3가지 핵심 모듈

  1. jackson-core
    • low-level streaming API를 정의하며 JSON의 구체적인 구현을 포함하고 있다.
  2. jackson-annotation
    • Jackson 라이브러리의 표준 어노테이션을 포함하고 있다.
  3. jackson-databind
    • 스트리밍 패키지에 대한 데이터 바인딩 지원이 구현되어 있으며, 스트리밍과 어노테이션 패키지에 의존한다.

 

 

Maven 설정

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${jackson.version.core}</version>
</dependency>

 

 

ObjectMapper

ObjectMapper는 Jackson 라이브러리에서 Java 객체와 JSON 형식 간의 직렬화 및 역직렬화할 수 있도록 제공하는 기능이다.

 

직렬화(Serialization)

객체를 저장 가능한 상태 또는 전송 가능한 상태인 데이터 스트림 형태로 변환하는 것을 뜻한다.

Java Object → JSON

 

역직렬화(Deserialization)

직렬화의 반대로 데이터 스트림으로 전달받은 데이터를 객체로 변환하는 것을 뜻한다.

JSON → Java Object

 

 

ObjectMapper 사용

User 클래스

다음 코드는 name과 age 필드를 가진 User 클래스로, 예제에 사용될 생성자와 getter, toString 메서드가 구현되어 있다.

public class User {
    private String name;
    private int age;

    public User() {
    }

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

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

 

Object ↔ Json Sring

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTest {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        User user = new User("kim", 20);

        // 직렬화(Object to Json)
        String objectToJson = mapper.writeValueAsString(user);
        System.out.println(objectToJson);

        System.out.println();

        // 역직렬화(Json to Object)
        String jsonString = "{\\"name\\":\\"park\\",\\"age\\":30}";
        User jsonToObject = mapper.readValue(jsonString, User.class);
        System.out.println(jsonToObject);
        System.out.println(jsonToObject.getName());
        System.out.println(jsonToObject.getAge());
    }
}
// 출력
{"name":"kim","age":20}

User{name='park', age=30}
park
30
  • ObjectMapper의 writeValueAsString 메서드를 통해 객체를 Json 문자열로 변환할 수 있다.
  • ObjectMapper의 readValue 메서드를 통해 지정한 Object 타입으로 변환할 수 있다.
  • JSON 뿐만 아니라 List, Map 등 다양한 형식의 직렬화 및 역직렬화도 가능하다.

 

 

Jackson 라이브러리와 기본 생성자

만약, Jackson 라이브러리를 통해 역직렬화(Deserialization)를 할 때, 변환할 클래스에 기본 생성자가 없으면 다음과 같은 에러가 발생한다.

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of ...

이는 Jackson 라이브러리가 자바 리플렉션(Reflection)을 사용하기 때문이다.

자바 리플렉션은 구체적인 클래스 타입을 알지 못하더라도 해당 클래스의 타입, 변수, 메서드 등에 접근할 수 있도록 해주는 자바 API이다.

따라서 리플렉션의 동작에 의해 기본 생성자로 객체를 생성한 후 setter로 값을 주입하게 된다.

 

기본 생성자 없이 역직렬화하기

Jackson 라이브러리에서는 기본 생성자 없이 특정 생성자를 통해 역직렬화하도록 설정할 수 있다.

라이브러리에서 제공하는 어노테이션을 통해 설정할 수 있다.

public class User {
    private String name;
    private int age;

    @JsonCreator
    public User(@JsonProperty("name") String name,
                @JsonProperty("age") int age) {
        this.name = name;
        this.age = age;
    }

    ...
}
  • 다음과 같이 생성자에 @JsonCreator 어노테이션을 설정하고, 파라미터에 @JsonProperty 어노테이션을 지정한다.
  • 위와 같이 작성하면 Jackson 라이브러리를 사용하여 역직렬화할 때 해당 생성자를 기본으로 사용하게 된다.
반응형