일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |
- 직무역량캠프
- UXUIPrimary
- 국비지원취업
- 국비지원
- 디자인챌린지
- 오픈패스
- baekjoon
- 오픈챌린지
- 디자인강의
- 백준
- KDT
- 국비지원교육
- 기초
- Be
- knu
- javascript
- 환급챌린지
- OPENPATH
- 구현
- js
- UXUI챌린지
- 백엔드개발자
- 백엔드 부트캠프
- 코드스테이츠
- 디자인교육
- 부트캠프
- UXUI기초정복
- 내일배움카드
- 문자열
- 패스트캠퍼스
- Today
- Total
군만두의 IT 공부 일지
[Spring] ObjectMapper를 활용한 직렬화, 역직렬화 본문
목차
📅진행기간: 2024년 2월 5일 ~ 2024년 9월 20일
⭐요약
- ObjectMapper를 활용한 직렬화와 역직렬화 과정을 통해서, 자바 객체를 JSON 형태로 변환하고 그 반대 과정을 어떻게 수행하는지를 학습함.
⭐ObjectMapper란?
Spring Framework에서 데이터 전송은 주로 JSON 형태로 이루어지며, 이 데이터를 효율적으로 관리하기 위해 ObjectMapper 클래스를 사용함. ObjectMapper는 Jackson 라이브러리의 클래스로, 객체(DTO)를 JSON으로 변환하는 직렬화와 JSON을 객체(DTO)로 변환하는 역직렬화를 할 수 있음.
⭐ObjectMapper의 동작 원리
ObjectMapper는 JSON과 자바 객체 간의 변환을 쉽게 만들어, 개발자는 데이터 포맷의 변환에 대해 걱정할 필요 없이 로직 구현에 더 집중할 수 있음.
1) 직렬화: 자바 객체를 JSON으로 변환
직렬화 과정에서 ObjectMapper는 다음 단계로 진행함.
- 객체 생성과 설정: 자바에서는 DTO 객체를 생성하고 초기화함. DTO는 각 필드가 JSON의 키와 매치됨.
- ObjectMapper 인스턴스 사용: ObjectMapper의 writeValueAsString() 메소드나 writeValue() 메소드를 사용하여 DTO를 JSON 문자열이나 스트림으로 변환함.
- 필드 추출과 JSON 생성: 리플렉션을 사용하여 객체의 필드를 읽고, 각 필드에 대한 get 메소드를 호출하여 데이터를 추출함. 이 데이터는 JSON 키-값 쌍으로 변환되며, @JsonProperty를 사용해 JSON 키 이름을 변경할 수 있음.
예를 들어, 객체의 getName() 메소드에서 반환된 값은 JSON에서 'name' 키의 값으로 매핑됨. @JsonProperty("user_name") 어노테이션을 사용하여 JSON 키 이름을 'user_name'으로 변경할 수 있음.
2) 역직렬화: JSON을 자바 객체로 변환
역직렬화 과정은 다음 단계로 진행함.
- JSON 입력: 역직렬화 과정은 JSON 문자열이나 파일로부터 시작함.
- ObjectMapper 인스턴스 사용: ObjectMapper의 readValue() 메소드를 사용하여 JSON 데이터를 클래스 인스턴스로 변환함. 이 메소드는 JSON 키를 클래스의 필드와 매핑하고, 해당 필드에 적절한 데이터 유형으로 데이터를 설정함.
- 데이터 매핑과 객체 생성: ObjectMapper는 JSON 내의 각 키-값 쌍을 분석하여 해당 클래스의 필드에 할당함. 이 과정에서 @JsonNaming, @JsonProperty 등을 통해 필드 이름 매핑 규칙을 조정할 수 있음. 필드 타입에 맞게 자동으로 타입 변환을 수행함.
예를 들어 JSON 데이터 {"user_name": "mandus"}을 객체로 변환할 때, 클래스에 setUserName(String userName) 메소드나 userName 필드가 존재해야 하며, @JsonProperty("user_name") 어노테이션이 적용되어 있어야 함.
3) 유의사항
- 날짜 및 시간 포맷: 날짜와 시간 데이터는 직렬화와 역직렬화 과정에서 포맷이 중요함. ObjectMapper는 @JsonFormat 어노테이션을 사용하여 이러한 필드의 포맷을 정의할 수 있음.
- 무시할 필드 설정: 어떤 필드가 JSON에 포함되지 않도록 하거나 JSON에서 읽지 않도록 설정하려면 @JsonIgnore 어노테이션을 사용할 수 있음.
- 커스텀 직렬화/역직렬화: 특정 필드나 클래스에 대한 직렬화 및 역직렬화 방식을 커스텀하고 싶다면 JsonSerializer와 JsonDeserializer를 구현할 수 있음.
⭐직렬화와 역직렬화
직렬화 및 역직렬화 과정에는 다음과 같이 2개의 클래스가 필요함. 테스트는 main 패키지가 아닌, test 패키지 내 ApplicationTests 클래스를 실행할 것임.
1. UserRequest 클래스 정의
먼저, UserRequest 클래스는 Lombok 라이브러리의 @Data, @AllArgsConstructor, @NoArgsConstructor 어노테이션을 사용하여 간결하게 필드와 생성자, getter/setter 메소드를 자동으로 생성함. 그리고 Jackson의 @JsonNaming 어노테이션을 통해 JSON 키를 snake case 형식으로 자동 변환함.
package com.example.demo.model;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class UserRequest {
private String userName;
private Integer userAge;
private String email;
private Boolean isKorean;
}
2. 직렬화 테스트 코드
Spring Boot의 테스트 환경에서 ObjectMapper를 사용하여 객체를 JSON 문자열로 변환하는 과정을 구현함.
package com.example.demo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private ObjectMapper objectMapper;
@Test
void contextLoads() throws JsonProcessingException {
var user = new UserRequest();
user.setUserName("mandus");
user.setUserAge(10);
user.setEmail("test@gmail.com");
user.setIsKorean(true);
var json = objectMapper.writeValueAsString(user);
System.out.println(json);
}
}
코드를 실행하면 사진과 같이 UserRequest가 담고 있는 내용이 JSON으로 바뀐것을 확인할 수 있음.
// 직렬화 결과
{"user_name":"mandus","user_age":10,"email":"test@gmail.com","is_korean":true}
3. 역직렬화 테스트 코드
직렬화 코드에서 JSON 문자열을 UserRequest 클래스의 인스턴스로 변환하는 코드를 추가함.
package com.example.demo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Autowired
private ObjectMapper objectMapper;
@Test
void contextLoads() throws JsonProcessingException {
var user = new UserRequest();
user.setUserName("mandus");
user.setUserAge(10);
user.setEmail("test@gmail.com");
user.setIsKorean(true);
var json = objectMapper.writeValueAsString(user);
System.out.println(json);
var dto = objectMapper.readValue(json, UserRequest.class);
System.out.println(dto);
}
}
역직렬화 코드를 추가해서 실행하면 JSON으로 만들어진 내용이 다시 객체로 맵핑됨.
// 역직렬화 결과
UserRequest(userName=mandus, userAge=10, email=test@gmail.com, isKorean=true)
Spring Boot는 기본적으로 ObjectMapper가 동작함. POST나 RequestBody에 있는 JSON 형태의 데이터들을 자바 객체(DTO)로 맵핑하는 역할(역직렬화)을 함. 반대로, 자바 객체를 JSON으로 변환하는 직렬화 과정도 ObjectMapper에 의해 자동으로 처리됨.
이것은 주로 @RequestBody 어노테이션이 적용된 컨트롤러 메소드에서 HTTP 요청 본문의 JSON 데이터를 자바 객체로 변환할 때, 또는 @ResponseBody 어노테이션을 통해 자바 객체를 HTTP 응답 본문의 JSON으로 출력할 때 사용됨.
⭐JVM 경고 메시지 해결
JUnit 테스트를 실행할 때 사진과 같은 JVM 관련 경고가 나타남.
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
이것을 해결하기 위해 build.gradle 파일에 다음과 같은 설정을 추가함.
tasks.named('test') {
useJUnitPlatform()
jvmArgs '-Xshare:off'
}
이렇게 클래스 데이터 공유 기능을 비활성화하면, 클래스 로더 관련 경고를 해결할 수 있음.
⭐후기
- 직렬화와 역직렬화라는 개념에 대해서 이론만 알고 있었는데, 직접 코드로 구현해보면서 이해할 수 있었음.
- Spring Boot에서 ObjectMapper를 사용하면 데이터의 직렬화와 역직렬화를 통해 웹 애플리케이션 간의 통신을 간소화하여 보다 효율적으로 데이터를 처리할 수 있다는 것을 알게 되었음.
⭐참고자료
1) RyanGomdoriPooh, "Jackson ObjectMapper 정리", 2021.06.14, https://interconnection.tistory.com/137
2) zooneon, "[Java] ObjectMapper를 이용하여 JSON 파싱하기", 2021.07.05, https://velog.io/@zooneon/Java-ObjectMapper를-이용하여-JSON-파싱하기
3) 오늘도 개발자, "[Jackson]Custom Serializer, Deserializer 를 만들어 사용하기!", 2020.01.02, https://akageun.github.io/2020/01/02/java-jackson-custom-serialize.html
4) jaemoon, "OpenJDK 64-bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended경고가 뜹니다.", 2024.02.06, https://www.inflearn.com/questions/1169397/openjdk-64-bit-server-vm-warning-sharing-is-only-supported-for-boot-loader-clas
이 글은 패스트캠퍼스의 백엔드 개발 캠프에서 공부한 내용을 작성한 것입니다.
'개발일지 > 패스트캠퍼스' 카테고리의 다른 글
REST API란? (0) | 2024.04.12 |
---|---|
[Java] JSON 라이브러리 사용 방법 및 성능 비교 (0) | 2024.04.07 |
[Java] 패스트캠퍼스 백엔드 개발 부트캠프 8기 토이 프로젝트 1 DAY5 (0) | 2024.04.05 |
[Java] 패스트캠퍼스 백엔드 개발 부트캠프 8기 토이 프로젝트 1 DAY4 (0) | 2024.04.04 |
[Java] 패스트캠퍼스 백엔드 개발 부트캠프 8기 토이 프로젝트 1 DAY3 (0) | 2024.04.04 |