티스토리 뷰

build.gradle 작성

  • 프로젝트 루트의 build.gradle에 아래 내용을 추가한다.
dependencies {
    compile group: 'org.projectlombok', name: 'lombok', version: '1.18.0'
    compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.6'
}

@Configuration 작성

  • Spring Boot는 기본적으로 ObjectMapper 빈을 제공한다. 하지만 다양한 상황에 대응할 수 있도록 입맛에 맞게 사용하려면 아래와 같이 커스터마이징된 별도의 빈을 등록하는 방법을 추천한다.
@Configuration
public class JsonConfig {

    @Bean("objectMapper")
    public ObjectMapper objectMapper() {
        return Jackson2ObjectMapperBuilder.json()

                .featuresToDisable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
                .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                .modules(new JavaTimeModule())
                .build();
    }
}
  • JSONPOJO로 변환할 때 맵핑되는 필드가 전혀 존재하지 않으면 기본적으로 예외가 발생한다. 예외 발생을 원하지 않을 경우 SerializationFeature.FAIL_ON_EMPTY_BEANS 옵션을 비활성화하면 예외 없이 비어있는 POJO를 반환한다.
  • POJOJSON으로 변환할 때 날짜, 시간 타입의 데이터는 기본적으로 오브젝트의 형태가 그대로 변환되어 가독성이 심하게 떨어진다. 특히 주 용도가 REST API일 경우 특히 문제가 된다. SerializationFeature.WRITE_DATES_AS_TIMESTAMPS 옵션을 비활성화하고 JavaTimeModule 모듈을 등록하면 적절히 ISO 8601 형식의 문자열로 변환해준다.

POJO 작성

  • POJOJava 진영에서 귀차니즘의 주인공이자 동시에 가장 큰 무기이기도 하다. 특정 JSON을 변환하기 위해 반드시 POJO를 작성해야 한다는 것은 타언어(특히 PHPNode.js)에서 넘어온 개발자들이 보기엔 여간 불편할 수 없다. 하지만 한번 잘 설계된 POJO를 갖게 되면 상당히 직관적인 도메인 주도 개발이 가능해진다. 동시에 컴파일 오류까지 줄여주고 소스 코드 가독성까지 상승하므로 되도록 POJO 작성에 익숙해지기를 추천한다.
@NoArgsConstructor
@Setter
@JsonPropertyOrder(value = {"error_code", "error_message", "error_data"})
public class Error {

    @JsonProperty("error_code")
    @Getter
    private String errorCode;

    @JsonProperty("error_message")
    @Getter
    private String errorMessage;

    @JsonProperty("error_data")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @Getter
    private Map errorData;

    public Error(String errorCode, String errorMessage, Map errorData) {

        this.errorCode = errorCode;
        this.errorMessage = errorMessage;
        this.errorData = errorData;
    }
}
  • 프라퍼터에 @JsonProperty를 명시하면 JSON으로 변환시 출력될 키의 이름을 맵핑할 수 있다. 반대로 POJO로 변환시 어느 프라퍼티에 저장할지를 결정하는 지시자 역할도 한다. JSONPOJO 간의 불일치 문제를 해소하고 소스 코드에서 Java만의 네이밍 컨벤션을 사용할 수 있어 매우 유용하다.

  • 프라퍼티에 @JsonInclude(JsonInclude.Include.NON_EMPTY)을 명시하면 해당 값이 null이거나 비어 있는 오브젝트로 간주될 경우 JSON으로 변환시 해당 프라퍼티가 아예 생략된다. 값의 존재 유무에 따라 선택적으로 JSON 출력을 해야할 경우 매우 유용하다.

  • 프라퍼티에 @JsonIgnore를 명시하면 JSON으로 변환시 해당 프라퍼티는 무조건 출력을 생략한다. 바깥으로 보여지지 말아야할 내부 프라퍼티일 경우 제외할 수 있어 유용하다. 클래스에 @JsonIgnoreProperties를 명시하여 변환을 무시할 프라퍼티를 한꺼번에 지정할 수도 있다.

  • 클래스에 @JsonPropertyOrder를 명시하면 JSON으로 변환시 출력될 프라퍼티의 순서를 결정할 수 있다. 순서의 기준은 프라퍼티 이름이 아닌 @JsonProperty에 명시된 키 이름이 기준이어야 함을 명심한다.

POJO-JSON 상호 변환

  • POJOJSON을 상호 변환하는 방법은 아래와 같다.
@Component
public class SomeComponent {

    @Autowired
    @Qualifier("objectMapper")
    private ObjectMapper objectMapper;

    public Error convertJson2Pojo(String errorJson) throws IOException {

        return objectMapper.readValue(errorJson, Error.class);
    }

    public String convertPojo2Json(Error error) throws IOException {

        return objectMapper.writeValueAsString(Error.class);
    }
}
댓글
댓글쓰기 폼