티스토리 뷰

개요

JacksonJava 진영의 대표적인 POJO-JSON 상호 변환 라이브러리이다. 이번 글에서는 @JsonFilter를 이용하여 POJO 오브젝트의 필드 값을 기준으로 조건에 맞는 필드만 선택적으로 JSON으로 변환하는 예를 소개하고자 한다.

라이브러리 종속성 추가

dependencies {
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.8.1'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.1'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.8.1'
    compile group: 'org.projectlombok', name: 'lombok', version: '1.16.10'
}
  • Spring Boot(1.4.0) 기반의 웹 프로젝트라면 Jackson이 이미 추가되어 있으므로 별도로 추가할 필요가 없다.

  • 필수는 아니지만 POJO 클래스를 효율적으로 작성하기 위해 lombok 아티팩트를 추가하였다.

POJO 클래스 작성

package com.jsonobject.example;

import com.fasterxml.jackson.annotation.JsonFilter;
import lombok.Data;

@JsonFilter("userJsonFilter")
@Data
public class User {

    private int id;

    private String email;

    private String password;

    private boolean hasProfileImage;

    private String profileImageUrl;
}
  • 간단한 회원 정보를 저장하는 목적의 일반적인 POJO 클래스를 작성하였다. Lombok이 제공하는 @Data 클래스 레벨 어노테이션으로 RequiredArgsConstructor, Getter, Setter 작성을 생략하였다.

  • @JsonFilter 클래스 레벨 어노테이션으로 JSON 변환시 사용할 필터를 명시하였다. (필터 작성 및 등록은 아래 설명할 것이다.)

JsonFilter 클래스 작성

package com.jsonobject.example;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;

public class UserJsonFilter extends SimpleBeanPropertyFilter {

    @Override
    public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception {

        if (pojo instanceof User) {
            if (canSerializeAsField((User) pojo, writer.getName())) {
                super.serializeAsField(pojo, jgen, provider, writer);
            }
        } else {
            super.serializeAsField(pojo, jgen, provider, writer);
        }
    }

    private boolean canSerializeAsField(User user, String fieldName) {

        if (fieldName.equals("password")) {
            return false;
        }
        if (fieldName.equals("profileImageUrl") && !user.isHasProfileImage()) {
            return false;
        }

        return true;
    }
}
  • SimpleBeanPropertyFilter.serializeAsField() 메써드는 JSON 변환 시점에 대상 POJO의 모든 필드에 대해 실행된다. 이를 통해 필드 단위로 변환 여부를 결정할 수 있다.

  • POJO 단위로 대응 필터를 작성하여 JSON 변환 정책을 세울 수 있다. 위의 경우 회원 정보를 담는 User 클래스에 대해 아래 정책을 적용하였다.
1. password 필드는 JSON으로 변환하지 않는다.
2. hasProfileImage 필드의 값이 true일 경우에만 profileImageUrl을 JSON으로 변환한다.

ObjectMapper 필터 등록 및 변환

User user = new User();
user.setId(1);
user.setEmail("someone@gmail.com");
user.setPassword("secret");
user.setHasProfileImage(false);
user.setProfileImageUrl(null);

ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(new SimpleFilterProvider().addFilter("userJsonFilter", new UserJsonFilter()));
mapper.writeValueAsString(user));

변환 결과는 아래와 같다. 필터가 정상적으로 적용되었음을 확인할 수 있다.

{
  "id" : 1,
  "email" : "someone@gmail.com",
  "hasProfileImage" : false
}

참고 글

댓글
댓글쓰기 폼