✅Object Mapper
Java Object와 JSON의 형태를 자유롭게 변경하기 위해 사용되는 것이 Object Mapper이다.
- Serialize: Java Object → JSON
- Deserialize: JSON → Java Object
형태를 바꿔주는 기능은 위의 두 가지 방식으로 나누어져 있으며 Object Mapper의 가장 중요한 기능이다
dependencies {
...
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0'
}
이렇게 Gradle에 의존성을 추가해도되지만
implementation 'org.springframework.boot:spring-boot-starter-web'
해당 의존성에 자동으로 포함되어있어서 따로 추가적으로 의존성을 추가안해도된다.
처음에 이것을 쓰게된 계기는 Naver OpenApi에서 책 검색기능을 구현하는데 Json 으로 데이터가 왔다.
Json으로 온데이터를 Java쪽에서 추가적으로 로직을 수행하기 위해서 이다.
🔎 예제
public class Member {
private int id;
private String name;
public Member(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
위와 같은 Java class가 있다고 가정하자. 이 Member class를 이용하여 어떻게 serialization, deserialization이 가능한 것인지 알아볼 것이다.
✅ Serialization (Java Object → JSON)
JSON의 형태로 serialize 시킬 때 objectMapper의 writeValue() 와 writeValueAsString() 메소드를 사용한다. 이 두 메소드는 각각 파일로 변환, 문자열로 변환의 기능을 갖고 있다
public class ObjectMapperPractice {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
Member member = new Member(1, "Sangyup");
// Java Object -> JSON
// 파일 출력: member.json
try {
objectMapper.writeValue(new File("원하는 경로/member.json"), member);
} catch (IOException e) {
e.printStackTrace();
}
// 문자열 출력
try {
String memberAsJsonString = objectMapper.writeValueAsString(member);
System.out.println(memberAsJsonString);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
// 출력값: {"id":1,"name":"Sangyup"}
}
}
이 때, serialize 하려고 하는 class에 Getter가 없다면 안된다.
Jackson 라이브러리는 serialize할 때, Getter의 prefix를 제거하고 소문자로 만들어서 식별하기 때문에 가져올 Getter가 없다면 오류를 내보내게 된다.
✅ Deserialization (JSON → Java Object)
SON을 Java Object로 deserialize시킬 때는 objectMapper의 readValue() 메소드를 이용한다
public class ObjectMapperPractice {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
// JSON -> Java Object
String json = "{\"id\":2, \"name\":\"Sangyup Lee\"}";
try {
Member newMember = objectMapper.readValue(json, Member.class);
System.out.println(newMember);
System.out.println(newMember.getId() + " " + newMember.getName());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
역직렬화를 진행시 해당 클래스에는 기본생성자가 있어야지 Java Object가 생성된다.
🖥️ Naver OpenAPI 역직렬화
@Override
public List<BookDto> searchBooks(String query, Integer display) {
String encodedQuery = URLEncoder.encode(query, StandardCharsets.UTF_8);
String apiURL = NAVER_BOOK_API_URL + "?query=" + encodedQuery + "&display=" + display;
Map<String, String> requestHeaders = new HashMap<>();
requestHeaders.put("X-Naver-Client-Id", clientId);
requestHeaders.put("X-Naver-Client-Secret", clientSecret);
String responseBody = get(apiURL,requestHeaders);
List<BookDto> books = new ArrayList<>();
try {
ObjectMapper mapper = new ObjectMapper();
NaverBookResponse bookResponse = mapper.readValue(responseBody, NaverBookResponse.class);
if (bookResponse != null && bookResponse.getItems() != null && !bookResponse.getItems().isEmpty()) {
books = bookResponse.getItems().stream().map(this::convertToBookDto)
.collect(Collectors.toList());
logger.info("검색 결과: {} 건", books.size());
} else {
logger.info("검색 결과 없음: {}", query);
}
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
return books;
}
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class NaverBookResponse {
private List<NaverBookItem> items; // Book Item
private Integer total; // 전체 카운트
}
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class NaverBookItem {
private String title; // 제목
private String author; // 작가
private String publisher; // 출판사
private String pubdate; // 출판날짜
private String description; // 설명
private String isbn; // ISBN
private String image; // 이미지 URL
private String link; // 상세 정보 URL
private String discount; // 재고
}
✏️ 공부한점
API에서 받아온 Json 데이터를 Java Object로 만들기위해서 mapper.readValue를 사용했다.
readValue( "지적된 타입으로 변환할 대상", "대상을 어떤 타입으로 변환할 것인지 클래스명시 ")
'Back-end > SpringBoot' 카테고리의 다른 글
| [ SpringBoot] AOP (4) | 2025.07.25 |
|---|---|
| [SpringBoot] @JsonIgnoreProperties(ignoreUnknown=true) (0) | 2025.05.30 |
| [SpringBoot] @Transactional 트랜잭션 사용법 및 옵션 (0) | 2025.01.24 |
| [SpringBoot] REST API 구조 설계 및 SpringBoot 응답 클래스 만들기(feat. SingleResult, ListResult) (0) | 2024.12.19 |
| [Springboot] REST API 만들고 슬라이스 테스트하기 (feat. HAL Explorer 사용하기) (0) | 2024.12.02 |