🐛 Jackson 충돌: JSON parse error 해결

2025. 9. 5. 16:39·트러블슈팅

개요

 

Jackson에 대해 설명하자면, Jackson은 Spring Boot에서 JSON API를 만들 때 없어서는 안 될 핵심 라이브러리이다.

우리 프로젝트에서는 기존에 다른 DTO들이 공공데이터 API 응답 형태에 맞춰 Root Wrapping(@JsonRootName("response"))을 사용하도록 설정되어 있다. 이로 인해 Jackson의 전역 설정에서 Root Wrapping이 활성화되어 있는 상황이다.

그런데 문제가 생겼다. 클라이언트 요청을 받는 특정 DTO에서는 Root Wrapping을 적용하지 않고 일반적인 JSON 형태로 받아야 하는데, 자꾸 Root Wrapping이 강제 적용되고 있다.

그래서 자꾸 아래와 같은 에러코드가 뜨는 것... 해결해보자~~!

 

 

에러코드

 
JSON parse error: Root name ('contentId') does not match expected ('PlaceActionRequestDto')
for type com.comma.soomteum.domain.userPlace.dto.PlaceActionRequestDto

 

 

원인 분석

 

 

1단계: DTO 일관성 조사

  • Root Wrapping 사용하는 DTO (3개): 외부 API 응답용
    • PlaceDetailResponseDto.java:20 - @JsonRootName("response")
    • TatsCnctrResponse.java:15 - @JsonRootName("response")
    • KorService2Response.java:17 - @JsonRootName("response")
  • Root Wrapping 사용하지 않는 DTO (13개): 일반 요청/응답용
    • PlaceActionRequestDto.java ← 문제의 DTO
    • 기타 모든 요청 DTO들

2단계: Jackson 설정 추적

  1. TourAPI 호출자들의 설정: // TatsCnctrApiCaller.java:50 objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);

// KorApiCaller.java:43

objectMapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); 2. 핵심 문제 발견: // TatsCnctrApiCaller.java:45 private final ObjectMapper objectMapper; // ← Spring 기본 ObjectMapper 주입받음!

 

 

해결 시도

 

❌ 1차 시도: JacksonConfig.java 생성

 

@Bean @Primary public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false); return mapper; }

→ 실패: Spring Boot는 application.properties 우선

 

❌ 2차 시도: application.properties 설정

 

spring.jackson.deserialization.unwrap-root-value=false

→ 실패: TatsCnctrApiCaller가 이미 Spring의 ObjectMapper를 오염시킴

 

✅ 3차 시도: ObjectMapper 분리

 

// 수정 전 (문제) private final ObjectMapper objectMapper; // Spring 기본 ObjectMapper 주입

// 수정 후 (해결)

private final ObjectMapper objectMapper = new ObjectMapper(); // 별도 인스턴스

 

 

즉...

  1. 외부 API 팀: "우리는 Root Wrapping 필요해!" (UNWRAP_ROOT_VALUE=true)
  2. 일반 DTO 팀: "우리는 Root Wrapping 없어도 돼!" (UNWRAP_ROOT_VALUE=false)
  3. Spring ObjectMapper: "나는 하나인데 누구 말을 들어야 하지?" 😵

이랬던 것이다. ㅠㅠ

 

 

마무리

 

1. Spring의 전역 ObjectMapper Bean을 주입받아 런타임에 설정을 변경하면, 애플리케이션 전체에 영향을 미쳐 예상치 못한 부작용을 일으킬 수 있다.

2. 외부 API용과 내부 DTO용 Jackson 설정이 다를 때는 ObjectMapper를 완전히 분리해야 하며, 용도별로 별도 인스턴스를 사용하는 것이 안전하다.

3. 의존성 주입의 편리함에 의존하기보다는, 설정 충돌 가능성을 미리 고려하여 격리된 구조로 설계하는 것이 중요하다.

 

생각하고 개발하자!

'트러블슈팅' 카테고리의 다른 글

🐛 인텔리제이 Claude MCP failed 오류  (0) 2025.09.04
🐛 Swagger Failed to load API definition.  (2) 2025.07.10
'트러블슈팅' 카테고리의 다른 글
  • 🐛 인텔리제이 Claude MCP failed 오류
  • 🐛 Swagger Failed to load API definition.
hissic
hissic
더 나은 내일을 향해~!! 아자아자화이팅
  • hissic
    터벅터벅 나의 코딩일지
    hissic
  • 전체
    오늘
    어제
    • 분류 전체보기 (10) N
      • 스프링 (6) N
        • 개념 (4) N
      • 트러블슈팅 (3)
      • 도커 (0)
      • 회고 (0)
      • 프로젝트 (1) N
        • 숨틈 (0)
        • 원스어폰타임 (1) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
hissic
🐛 Jackson 충돌: JSON parse error 해결
상단으로

티스토리툴바