Java JSON 처리 실전 시리즈 5화 – JSON 필드명 자동 변환: CamelCase ↔ Snake_Case 대응 전략
Jackson을 이용해 JSON 필드명을 자동으로 camelCase ↔ snake_case로 변환하는 방법을 소개합니다. @JsonProperty, @JsonNaming, application.yml 설정까지 실무 예제 기반으로 정리합니다.
백엔드 개발자라면 이런 상황을 한 번쯤 겪어봤을 것입니다.
- Java 객체는 camelCase로 선언
- 프론트엔드나 외부 API는 snake_case JSON 포맷 요구
이때마다 @JsonProperty("user_name")을 필드마다 붙이자니 번거롭고, 유지보수성도 떨어집니다.
이 글에서는 Jackson에서 제공하는 자동 네이밍 전략을 통해 코드는 camelCase로 유지하면서, JSON은 snake_case로 제공하는 방법을 설명합니다.
1. 문제 예시
public class User {
private String userName;
private LocalDateTime createdAt;
}
기본 직렬화 결과:
{
"userName": "홍길동",
"createdAt": "2025-05-10T10:00:00"
}
→ 원하는 결과는 다음과 같은 snake_case 포맷일 수 있습니다:
{
"user_name": "홍길동",
"created_at": "2025-05-10T10:00:00"
}
2. 해결 방법 ①: application.yml 전역 설정
Spring Boot에서는 application.yml 설정만으로 Jackson의 네이밍 전략을 전역 적용할 수 있습니다.
spring:
jackson:
property-naming-strategy: SNAKE_CASE
설정 적용 후 컨트롤러 반환값 예시:
@GetMapping("/user")
public User getUser() {
return new User("홍길동", LocalDateTime.now());
}
출력 결과:
{
"user_name": "홍길동",
"created_at": "2025-05-10T10:00:00"
}
유지보수 관점에서 가장 간단하고 강력한 방법입니다.
3. 해결 방법 ②: 클래스 단위 @JsonNaming 적용
특정 클래스에서만 네이밍 전략을 다르게 적용하고 싶은 경우 유용합니다.
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class User {
private String userName;
private LocalDateTime createdAt;
}
이 방식은 글로벌 설정을 변경하지 않고, 클래스 단위로 snake_case 변환을 적용합니다.
DTO 객체나 외부 API 모델 클래스에 주로 사용됩니다.
4. 해결 방법 ③: 필드 단위 @JsonProperty
public class User {
@JsonProperty("user_name")
private String userName;
@JsonProperty("created_at")
private LocalDateTime createdAt;
}
가장 낮은 우선순위를 가지며, 명시적 제어가 필요한 경우 사용합니다. 전역 설정 + 일부 필드만 예외 처리할 때 유용합니다.
5. SnakeCase ↔ CamelCase 매핑 테스트 예제
테스트 코드 예시 (Spring Boot Test + ObjectMapper 사용):
@SpringBootTest
public class JsonNamingTest {
@Autowired
private ObjectMapper objectMapper;
@Test
void testSnakeCaseMapping() throws Exception {
String json = "{\"user_name\":\"홍길동\",\"created_at\":\"2025-05-10T10:00:00\"}";
User user = objectMapper.readValue(json, User.class);
Assertions.assertEquals("홍길동", user.getUserName());
}
}
이 테스트는 역직렬화 방향에서도 snake_case → camelCase 매핑이 자동 적용되는지를 확인합니다.
6. 커스텀 네이밍 전략이 필요한 경우
Jackson은 기본적으로 UPPER_CAMEL_CASE, SNAKE_CASE, LOWER_CASE, KEBAB_CASE 등을 제공합니다.
하지만 복합적인 규칙이 필요한 경우에는 커스텀 전략 클래스를 작성할 수도 있습니다.
public class CustomNamingStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase {
@Override
public String translate(String input) {
// 사용자 정의 네이밍 규칙 작성
return "custom_" + input.toLowerCase();
}
}
그리고 다음과 같이 적용:
@JsonNaming(CustomNamingStrategy.class)
public class User {
...
}
결론 및 실무 팁 요약
전략 적용 대상 특징
application.yml | 전체 전역 | 가장 간단하고 강력 |
@JsonNaming | 클래스 단위 | DTO 분리 시 유용 |
@JsonProperty | 필드 단위 | 예외 상황 대응용 |
- 전역 네이밍 전략은 yml로 적용하고, 예외 상황만 어노테이션으로 보완하는 것이 유지보수에 유리합니다.
- 팀 내 API 명세 스타일을 정하고, 일관되게 전략을 유지하는 것이 중요합니다.
다음 회차 예고
6화에서는 Spring MVC 컨트롤러에서 JSON 요청과 응답을 어떻게 처리하는지 흐름을 파악하고, @RequestBody, @ResponseBody, HttpMessageConverter 동작 원리를 Jackson과 함께 분석합니다.