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의 명시적 변환 없이도 동일 효과를 얻을 수 있습니다.