Jackson과 Fastjson JSON 응답 필드 매핑 및 널값 처리

REST API 개발 중 Jackson과 Fastjson을 혼용할 때 발생하는 필드명 변환 실패 및 null 필드 누락 문제를 해결한 경험을 정리합니다.

핵심 문제 상황

외부 시스템 연동 시 대문자 스네이크 케이스(EMPLOYEE_ID)로 응답해야 하는데, 기본 설정에서는 카멜 케이스(employeeId)로 변환되어 전송되었습니다. 또한 값이 null인 필드가 JSON 응답에서 완전히 제외되는 문제도 함께 발생했습니다.

엔티티 클래스 구성

두 라이브러리를 동시에 지원하기 위한 어노테이션 적용 예시입니다:

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonProperty;

public class StaffMember {
    
    @JSONField(name = "STAFF_CODE")
    @JsonProperty("STAFF_CODE")
    @JsonAlias("STAFF_CODE")
    private String staffCode;
    
    @JSONField(name = "FULL_NAME")
    @JsonProperty("FULL_NAME")
    @JsonAlias("FULL_NAME")
    private String fullName;
    
    @JSONField(name = "DEPARTMENT")
    @JsonProperty("DEPARTMENT")
    @JsonAlias("DEPARTMENT")
    private String department;
    
}

각 라이브러리별 동작 방식

라이브러리직렬화역직렬화
Jackson@JsonProperty@JsonAlias
Fastjson@JSONField(name)

실제 적용 시 주의사항

Spring Boot 기본 설정으로는 위 어노테이션만으로 의도한 대문자 필드명이 적용되지 않았습니다. 컨트롤러에서 객체를 직접 반환하는 방식과 문자열로 변환 후 반환하는 방식의 차이를 확인했습니다.

방식 1: 객체 직접 반환 (Jackson 기본)

@PostMapping(value = "/staff/list", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public List<StaffMember> fetchStaffList() {
    List<StaffMember> result = staffService.findAllActive();
    // 기본 설정 시 필드명이 소문자로 출력됨
    return result;
}

방식 2: Fastjson 문자열 변환 (정상 동작)

@PostMapping(value = "/staff/list", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String fetchStaffListAsString() {
    List<StaffMember> result = staffService.findAllActive();
    // SerializerFeature로 null 필드 포함 및 필드명 변환 적용
    return JSON.toJSONString(result, SerializerFeature.WriteMapNullValue);
}

Fastjson 출력 제어 옵션

SerializerFeature 열거형으로 세밀한 출력 제어가 가능합니다:

// 여러 옵션 조합 사용
SerializerFeature[] features = {
    SerializerFeature.WriteMapNullValue,      // null 값 필드 포함
    SerializerFeature.WriteNullListAsEmpty,   // null 리스트를 []로
    SerializerFeature.WriteNullNumberAsZero,  // null 숫자를 0으로
    SerializerFeature.WriteNullBooleanAsFalse // null 불리언을 false로
};

String jsonOutput = JSON.toJSONString(data, features);

권장 해결책

프로젝트 표준 직렬화 도구를 단일화하거나, Spring Boot의 HttpMessageConverter를 커스터마이징하여 일관된 동작을 보장하는 것이 유지보수에 유리합니다. Fastjson을 주력으로 사용할 경우 FastJsonHttpMessageConverter를 등록하여 방식 2의 명시적 변환 없이도 동일 효과를 얻을 수 있습니다.

태그: Jackson Fastjson JSON Serialization Spring Boot SerializerFeature

9월 8일 02:04에 게시됨