java에서 jackson라이브러리를 사용하여 Json DTO에 프로퍼티들의 표기법을 변경할 수 있다
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserRequest {
private String userName;
private Integer userAge;
private String email;
private Boolean isKorean;
이 DTO를 보면 카멜케이스로 작성되어 있는 Json data를 받는 dto인데 아래와 같은 컨트롤러에서
Json 데이터로 값을 넘기는걸 테스트 해보자
@RequestMapping("/api")
@RestController
public class PostApiController {
@PostMapping("/test")
public String test(@RequestBody UserRequest request) {
System.out.println(request);
return request.toString();
}
}
@RequestBody를 사용하면 Json 데이터가 자바 객체로 매핑되어 처리된다
당연히 성공한다 하지만 json 데이터의 이름 형식이
카멜 케이스가 아닌 아래와 같이 스네이크 케이스 작성된 경우엔 어떻게 해야할까
{
"user_name":"Gyuha" ,
"user_age":12,
"email":"gggg@gggg.com" ,
"is_korean":"true"
}
요청은 성공하였지만 들어간 값을 보면 null들이 들어가게되었다 그럼
당연히 DTO에 프로퍼티들 변수명이 일치 하지 않아서 그렇다고 생각할 수 있다 그렇 다면 한 번 아래와 같이 변경해보자
@AllArgsConstructor
@NoArgsConstructor
@Data
public class UserRequest {
private String user_name;
private Integer user_age;
private String email;
private Boolean is_korean;
요청도 성공적으로 처리되었고 값도 잘 들어갔다 그러면 이름에 맞게 프로퍼티의 이름도 바꿔주면 되는건가?
그렇지 않다
JSON 표기법중엔 여럿 표기법이 있는데
그중에서 JAVA에서 문제가 되는게 바로 kebab-case다
{
"user-name":"Gyuha" ,
"user-age":12,
"email":"gggg@gggg.com" ,
"is-korean":"true"
}
위와 같은 이름에 제이슨 데이터가 들어올때 프로퍼티에도 하이픈을 사용하야 하는데 JAVA에선 변수명에 하이픈을 사용하지 못하기 때문에 값들을 매핑 시킬 수 없다
응답은 됐으나 값들을 보면 제대로 들어가지 않았다
json 데이터의 이름을 매핑 시켜줄 수 있는게 @JsonNaming이다
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class)
@Data
public class UserRequest {
private String userName;
private Integer userAge;
private String email;
private Boolean isKorean;
위와 같이 JsonNaming에 매개변수로 어떤걸 주느냐에 따라서 dto에 이름이 바뀐다
지금은 KebabCaseStrategy.class로 해서 kebab-case로 변경 되었다
카멜 케이스로 표기한 변수들임에도 불구하고 케밥 케이스로 값을 전송해줘도 제대로 들어간다
@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class)
PropertyNamingStrategies.~~.class로 되어 있어야한다
PropertyNamingStrategies와 PropertyNamingStrategy가 있는데
전자를 사용하여야한다 PropertyNamingStrategy는 더이상 사용이 불가능하다
클래스에 직접 지정하는 @JsonNaming 말고도
@JsonProperty가 있는데 얘는 변수위에 직접 이름을 지정해줄 수 있따
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.KebabCaseStrategy.class)
@Data
public class UserRequest {
private String userName;
private Integer userAge;
@JsonProperty(user-email)
private String email;
private Boolean isKorean;
Json 데이터
{
"user-name":"Gyuha" ,
"user-age":12,
"user-email":"gggg@gggg.com" ,
"is-korean":"true"
}
성공
지금은 받아오는 데이터가 조금만 있어서 프로퍼티들을 직접변경해줘도 되지만 받아오는 데이터의 갯수가 증가할 수록 활용도는 더욱 높아질거 같다