기술과 산업/언어 및 프레임워크
Jackson JSON 트러블슈팅을 위한 각 오류별 구체적인 예제와 JUnit 기반 테스트 코드
B컷개발자
2025. 5. 19. 11:07
728x90
Jackson JSON 트러블슈팅을 위한 각 오류별 구체적인 예제와 JUnit 기반 테스트 코드를 정리한 Java 코드 문서를 생성했습니다. 이 문서에는 다음과 같은 내용을 포함하고 있습니다:
- UnrecognizedPropertyException (정의되지 않은 필드)
- InvalidFormatException (타입 불일치)
- JavaTimeModule 미등록으로 인한 날짜 오류
- Enum 역직렬화 실패
- 순환 참조 문제와 @JsonManagedReference, @JsonBackReference 사용 예제
// Java JSON 처리 실전 – Jackson 트러블슈팅 확장 예제 모음
// 1. UnrecognizedPropertyException 예제
public class User {
private String name;
private int age;
// getter, setter
}
@Test
void testUnrecognizedField() throws Exception {
String json = "{\"name\":\"홍길동\", \"age\":30, \"unknown\":\"test\"}";
ObjectMapper mapper = new ObjectMapper();
Assertions.assertThrows(UnrecognizedPropertyException.class, () -> {
mapper.readValue(json, User.class);
});
}
// 해결: 무시 설정 추가
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserSafe {
private String name;
private int age;
}
// 2. InvalidFormatException 예제
public class AgeUser {
private int age;
}
@Test
void testInvalidFormat() throws Exception {
String json = "{\"age\":\"abc\"}";
ObjectMapper mapper = new ObjectMapper();
Assertions.assertThrows(InvalidFormatException.class, () -> {
mapper.readValue(json, AgeUser.class);
});
}
// 3. JavaTimeModule 미등록 예제
public class DateUser {
private LocalDateTime createdAt;
}
@Test
void testMissingJavaTimeModule() throws Exception {
String json = "{\"createdAt\":\"2025-05-10T15:00:00\"}";
ObjectMapper mapper = new ObjectMapper();
Assertions.assertThrows(InvalidDefinitionException.class, () -> {
mapper.readValue(json, DateUser.class);
});
}
// 해결: 모듈 등록
@Test
void testWithJavaTimeModule() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
String json = "{\"createdAt\":\"2025-05-10T15:00:00\"}";
DateUser user = mapper.readValue(json, DateUser.class);
Assertions.assertNotNull(user.getCreatedAt());
}
// 4. Enum 역직렬화 오류 및 해결
public enum Role {
ADMIN, USER
}
public class RoleUser {
private Role role;
}
@Test
void testEnumFail() throws Exception {
String json = "{\"role\":\"admin\"}";
ObjectMapper mapper = new ObjectMapper();
Assertions.assertThrows(IllegalArgumentException.class, () -> {
mapper.readValue(json, RoleUser.class);
});
}
// 해결: 대소문자 무시
@Test
void testEnumSuccessWithInsensitive() throws Exception {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS, true);
String json = "{\"role\":\"admin\"}";
RoleUser user = mapper.readValue(json, RoleUser.class);
Assertions.assertEquals(Role.ADMIN, user.getRole());
}
// 5. 순환 참조 문제 해결
@Data
@NoArgsConstructor
@AllArgsConstructor
class Parent {
public String name;
@JsonManagedReference
public Child child;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Child {
public String name;
@JsonBackReference
public Parent parent;
}
@Test
void testCyclicReference() throws Exception {
Parent parent = new Parent("부모", null);
Child child = new Child("자식", parent);
parent.setChild(child);
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(parent);
Assertions.assertTrue(json.contains("부모"));
Assertions.assertTrue(json.contains("자식"));
Assertions.assertFalse(json.contains("parent")); // 역참조 제외됨
}
Spring Boot 통합 테스트 형식 주요 특징은 다음과 같습니다:
- @SpringBootTest, @AutoConfigureMockMvc를 사용한 테스트 환경 구성
- MockMvc를 통한 실제 HTTP 요청 시뮬레이션
- /user 엔드포인트: 정의되지 않은 필드(UnrecognizedPropertyException) 테스트
- /role 엔드포인트: 대소문자 민감한 Enum 역직렬화 오류와 그 해결 테스트
- Jackson2ObjectMapperBuilderCustomizer를 활용한 설정 커스터마이징 예제 포함
// Jackson 트러블슈팅 – Spring Boot 통합 테스트 기반 예제
@SpringBootTest
@AutoConfigureMockMvc
public class JacksonErrorIntegrationTest {
@Autowired
private MockMvc mockMvc;
@RestController
static class TestController {
@PostMapping("/user")
public ResponseEntity<String> createUser(@RequestBody User user) {
return ResponseEntity.ok("OK");
}
@PostMapping("/role")
public ResponseEntity<String> assignRole(@RequestBody RoleUser roleUser) {
return ResponseEntity.ok("OK");
}
}
static class User {
public String name;
public int age;
}
static class RoleUser {
public Role role;
}
enum Role {
ADMIN, USER
}
@Test
void unrecognizedFieldReturns400() throws Exception {
String invalidJson = "{\"name\":\"홍길동\", \"age\":30, \"unknown\":\"???\"}";
mockMvc.perform(post("/user")
.contentType(MediaType.APPLICATION_JSON)
.content(invalidJson))
.andExpect(status().isBadRequest());
}
@Test
void invalidEnumValueReturns400() throws Exception {
String json = "{\"role\":\"admin\"}";
mockMvc.perform(post("/role")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isBadRequest());
}
@TestConfiguration
static class CustomConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder -> builder.featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS);
}
}
@Test
void validEnumWithInsensitiveEnabled() throws Exception {
String json = "{\"role\":\"admin\"}";
mockMvc.perform(post("/role")
.contentType(MediaType.APPLICATION_JSON)
.content(json))
.andExpect(status().isOk());
}
}
이제 이 코드를 실제 Spring Boot 프로젝트의 통합 테스트로 실행할 수 있으며, 실무 현장에서 JSON 처리 트러블슈팅을 자동화 테스트로 검증하는 데 활용하실 수 있습니다.
728x90