JSON to Java Object | ObjectMapper

주싱·2021년 10월 25일
0

Java

목록 보기
3/6
post-thumbnail

1. Overview

Java에서 ObjectMapper를 활용하면 JSON 문자열을 정말 손쉽게 Object로 변환할 수 있다. 그런데 학습 하다보니 Object로 잘 정의되어 있는 정상적인 필드를 찾을 수 없다는 UnrecognizedPropertyException 예외가 발생했는데 해결한 내용을 정리해 본다. 예제에서 사용한 어노테이션은 Lombok을 사용했다.

2. Dependencies

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.3</version>
</dependency>

3. JSON to Java Object

우선 단순한 자바 클래스를 정의한다.

@ToString
public class Car {
    private String name;
    private double velocity;
    private int age;
}

그리고 아래와 같이 간단하게 JSON 문자열을 Java Object로 변환하는 코드를 작성할 수 있다.

@Test
@SneakyThrows
void JsonToObjectTest(){
    ObjectMapper mapper = new ObjectMapper();
    String jsonInString = "{\"name\" : \"스파크\", \"age\" : 2014, \"velocity\" : 120.12}";
    Car car = car = mapper.readValue(jsonInString, Car.class);
    System.out.println(car.toString());
}

그런데 다음과 같이 "name" 필드를 찾을 수 없다는 UnrecognizedPropertyException 예외가 발생한다. 분명히 "name" 필드는 객체에 정의되어 있는데 이상하다.

여기까지가 내가 아래의 몇몇 유명 블로그를 보고 너무 간단해서, 따라해본 건데 왜 안되는거지?

4. 해결책

찾아보니 보통 UnrecognizedPropertyException 예외가 발생하는 경우는 정말로 정의되어 있지 않은 필드를 키 값으로 가지는 항목을 인식했을 때이다. 이럴 때는 아래와 같이 찾지 못하는 필드는 무시하도록 설정할 수 있다고 한다. 그러나 나의 경우는 없는 필드가 아닌데 예외가 발생하는 경우였다.

@ToString
@JsonIgnoreProperties(ignoreUnknown = true)
public class Car {
    private String name;
    private double velocity;
    private int age;
}

설마해서 Car 클래스에 Setter를 정의해 보았더니 된다. 블로그 글들도 다시 보니 주석으로 표준 Setter, Getter 가 있다라고 흐릿하게 코멘트 달려있다. 실행이 안될 정도로 크리티컬한 코드면 그냥 샘플에 넣어주면 좋았겠다는 생각을 해보며 글을 정리해 본다.

@ToString
@Setter
public class Car {
    private String name;
    private double velocity;
    private int age;
}

21.12.02 추가

조금더 공부하다 보니 ObjectMapper 자체에서 객체의 Visibility 설정을 통해 클래스에 Setter 정의 없이도 Json to Object 매핑이 가능하다. 불변속성을 깨는 Setter 를 정의해서 찝찝했는데 이 방법이 내 경우에 최적의 방법이 아닐까 생각한다.

@Test
@SneakyThrows
void JsonToObjectTest(){
    ObjectMapper mapper = new ObjectMapper();
    mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
    String jsonInString = "{\"name\" : \"스파크\", \"age\" : 2014, \"velocity\" : 120.12}";
    Car car = car = mapper.readValue(jsonInString, Car.class);
    System.out.println(car.toString());
}

결과

잘 동작한다! 너무 편리하고 좋네!

profile
소프트웨어 엔지니어, 일상

0개의 댓글