프론트 엔드가 백엔드로 Http body에 JSON 형식의 데이터를 전송한다. 이 때, JSON의 key 값이 snake case인 경우 Spring Boot 서버는 @RequestBody를 이용하여 매핑하게 되면 값이 매핑되지 않아 JSON에 대응되는 DTO객체의 필드가 null로 세팅된다. (JSON은 snake case, DTO는 camel case이기 때문)
예를 들어 아래와 같은 DTO 객체인 경우 @ReqeustBody로 받게 되면 기본적으로 camel case로 매핑된다.
public class DemoDto {
private String demoName;
private Long demoAge;
@Override
public String toString() {
return "DemoDto{" +
"demoName='" + demoName + '\'' +
", demoAge=" + demoAge +
'}';
}
// getters and setters...
}
따라서 위처럼 camel case을 따르는 JSON 형태의 요청은 매핑이 되지만,
위와 같이 snake case를 따라는 JSON 형태의 요청은 매핑이 되지 않고 null 값이 채워짐을 알 수 있다. (각 Type의 초기값이 채워짐)
아래 코드처럼 @JsonNaming 어노테이션을 이용하면 class 단위로 매핑시의 naming strategy를 지정할 수 있다. naming strategy는 PropertyNamingStrategy.SnakeCaseStrategy.class와 같이 지정할 수 있으나 deprecated 되었으므로 더 이상 사용하지 말라고 한다.
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
@Getter
@Setter
@ToString
public class DemoDto {
private String demoName;
private Long demoAge;
}
대신 아래와 같이 사용하면 된다.
package com.example.demo.dto;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
@Getter
@Setter
@ToString
public class DemoDto {
private String demoName;
private Long demoAge;
}
다음을 같이 application.properties에 추가하게 되면 전역적으로 jackson naming strategy가 설정된다. 1번 방법에서 설정한 @JsonNaming 어노테이션을 이용한 방법은 이 전역 설정을 Override하여 작동한다. (전역 설정보다 우선한다)
spring.jackson.property-naming-strategy=SNAKE_CASE
package com.example.demo.dto;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class DemoDto {
private String demoName;
private Long demoAge;
}
별도의 어노테이션 없이 전역 설정만으로 위와 같이 snake case로 매핑된 것을 볼 수 있다.
@JsonProperty 어노테이션을 사용하면 각 필드에 별도의 JsonProperty 명을 지정할 수 있다.
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class DemoDto {
@JsonProperty("demo_name")
private String demoName;
@JsonProperty("demo_age")
private Long demoAge;
}
문제 없이 매핑된 것을 볼 수 있다. 참고로 프로퍼티 명을 지정하는 것이기에 다음과 같은 코드도 가능하다.
package com.example.demo.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class DemoDto {
@JsonProperty("demo_name")
private String demoName;
@JsonProperty("JsonPropertyDemoAge")
private Long demoAge;
}
정말 특별한 경우가 아니라면 전역적으로 설정하는 2번 방법을 사용하게 될 것 같다.