Object Mapper (Jackson 라이브러리 사용법)
Object Mapper
- 스프링 부트에서 직렬화, 역직렬화 수행해준다. (JACKSON 사용)
- JSON → DTO ( 역직렬화 )
- DTO → JSON (직렬화)
- 변수가 아닌 method에 매칭이 된다.
Object Mapper 불러오기
@SpringBootTest
class DemoApplicationTests {
@Autowired // 스프링에서 관리하는 빈들 중에 자동으로 생성되는 ObjectMapper를 가져오겠다.
private ObjectMapper objectMapper;
// dto를 json으로 바꾸는게 직렬화
@Test
void contextLoads() throws JsonProcessingException {
var user = new UserRequest();
user.setUserName("홍길동");
user.setUserAge(10);
user.setEmail("hong@gmail.com");
user.setIsKorean(true);
// dto -> json 직렬화
var json = objectMapper.writeValueAsString(user);
System.out.println(json); // {"user_name":"홍길동","email":"hong@gmail.com","is_korean":true,"user_age":10}
var dto = objectMapper.readValue(json, UserRequest.class);
System.out.println(dto); // UserRequest(userName=홍길동, UserAge=10, email=hong@gmail.com, isKorean=true)
}
- @Autowired : 스프링에서 관리하는 빈들 중에 타입에 맞는 객체를 자동으로 찾아서 주입해주는 기능
- 스프링 컨테이너 안에 있는 ObjectMapper 객체를 자동으로 넣어준다.
- ObjectMapper 는 스프링 부트가 기본적으로 자동으로 등록해주는 Bean이다.
🔨 Object Mapper 작동원리
⭐ Object Mapper는 필드를 직접 보는 것이 아니라 getter 메서드를 기준으로 JSON 직렬화를 수행한다.
- Jackson (ObjectMapper)은 기본적으로 JSON 직렬화(JSON 문자열 만들기)는 getter 메서드만 보고, 역직렬화(JSON 문자열 → 객체 만들기)는 setter 또는 생성자를 본다.
- getter는 get 표시된 메소드를 찾고, setter는 set 표시된 메소드를 찾음
아래와 같은 코드는 객체는 toString으로 값은 나오게 되지만, json이 빈 값으로 출력됨.
Test 코드
@SpringBootTest
class DemoApplicationTests {
@Autowired // 스프링에서 관리하는 빈들 중에 자동으로 생성되는 ObjectMapper를 가져오겠다.
private ObjectMapper objectMapper;
@Test
void contextLoads() throws JsonProcessingException {
var user = new UserRequest("홍길동",10,"hong@gma",true);
// dto 클래스에서 toString 실행
System.out.println(user); // UserRequest{userName='홍길동', UserAge=10, email='hong@gma', isKorean=true}
// dto -> json 직렬화
var json = objectMapper.writeValueAsString(user);
System.out.println(json); // {}
}
}
dto 코드
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class UserRequest {
private String userName;
private Integer userAge;
private String email;
private Boolean isKorean ;
@Override
public String toString() {
return "UserRequest{" +
"userName='" + userName + '\\'' +
", UserAge=" + userAge +
", email='" + email + '\\'' +
", isKorean=" + isKorean +
'}';
}
}
dto 코드가 위에처럼 있으면 @AllArgsConstructor 로 매개변수들을 받아 toString으로 객체를 return 해줄 수 있지만, objectMapper.writeValueAsString(user); 로 json 형태로 직렬화 할 수 없음.
- Jackson(ObjectMapper)은 기본적으로 getter 메서드가 있어야 필드를 직렬화함.
- @Getter 또는 직접 작성한 getXxx() 메서드가 필요
- toString()은 객체 문자열을 표현할 뿐, JSON 직렬화와 무관
dto 코드 개선
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class UserRequest {
private String userName;
private Integer userAge;
private String email;
private Boolean isKorean ;
// 메소드를 찾고 get을 찾음
public String getUserName() {
return userName;
}
public Integer getUserAge() {
return userAge;
}
@JsonProperty("user_email") //custom한 key 사용
public String getEmail() {
return email;
}
public Boolean getIsKorean() {
return isKorean;
}
@JsonIgnore // ❗JsonIgnore로 무시하지 않으면 이 친구도 포함되서 나옴
public String getUser(){
return userName;
}
@Override
public String toString() {
return "UserRequest{" +
"userName='" + userName + '\\'' +
", UserAge=" + userAge +
", email='" + email + '\\'' +
", isKorean=" + isKorean +
'}';
}
}
- 이렇게 하면 일단 메소드를 찾음, 메소드를 찾고 get을 찾아서 getUserName이면 get과 userName를 분리하며 userName에 해당하는 내용 return
- 직렬화 성공
- {"user_name":"홍길동","user_age":10,"user_email":"hong@gma","is_korean":true}
- 스네이크케이스 전략 적용(@JsonNaming)으로 userName이 user_name으로 변함
- @JsonProperty(”EMAIL")은 수동으로 JSON 키 이름 바꿀 수 있다.
- @JsonIgnore 해당 getter는 직렬화 대상에서 제외
- 제외하지 않을 경우 원하지 않는 직렬화 결과가 나옴
- {"user_name":"홍길동","user_age":10,"user_email":"hong@gma","is_korean":true, “user”:”홍길동”}
- “user”:”홍길동” 이 추가됨
역직렬화 dto
- @Setter를 붙여준다.
- @Getter 사용해도 가능한 것을 알 수 있음
- 둘 다 안할거면 @JsonProperty 를 다붙여준다.
@Setter
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class UserRequest {
private String userName;
private Integer userAge;
private String email;
private Boolean isKorean ;
private UserRequest(){
}
@Override
public String toString() {
return "UserRequest{" +
"userName='" + userName + '\\'' +
", UserAge=" + userAge +
", email='" + email + '\\'' +
", isKorean=" + isKorean +
'}';
}
}
- 둘 다 안할거면 @JsonProperty 를 다붙여준다.
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class UserRequest {
@JsonProperty("user_name")
private String userName;
@JsonProperty("user_age")
private Integer userAge;
@JsonProperty("user_email")
private String email;
@JsonProperty("is_korean")
private Boolean isKorean ;
@Override
public String toString() {
return "UserRequest{" +
"userName='" + userName + '\\'' +
", UserAge=" + userAge +
", email='" + email + '\\'' +
", isKorean=" + isKorean +
'}';
}
}
⭐ 가장 베스트 기본 형태 사용
그냥 자동으로 해주는 어노테이션 써라~
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class UserRequest {
private String userName;
private Integer userAge;
private String email;
private Boolean isKorean ;
}
'Spring > Spring Boot' 카테고리의 다른 글
[Spring Boot] 응답(response) 만들기! (0) | 2025.04.29 |
---|---|
[Spring Boot] REST API 사용, DTO (0) | 2025.04.29 |