밤빵's 개발일지
[WIL]20240915 JSON직렬화/역직렬화 본문
🤓JSON 직렬화/역직렬화
JSON 데이터를 다루는 과정에서 직렬화와 역직렬화에 대한 문제가 생겼다. 직렬화와 역직렬화는 데이터를 다른 형식으로 변환하고, 다시 원래 형태로 복원하는 과정인데, 이 과정에서 발생한 문제를 해결하고 이해하기 위해 이번 개발일지를 작성하게 되었다!
▶ JSON 직렬화와 역직렬화란?
먼저, 직렬화(Serialization)는 자바 객체를 JSON 형식으로 변환하는 과정이다. 이 과정은 데이터를 네트워크를 통해 전송하거나, 파일로 저장할 때 매우 유용하다. 반면, 역직렬화(Deserialization)는 JSON 데이터를 다시 자바 객체로 변환하는 과정이다. 서버나 클라이언트 간에 데이터를 주고받을 때, JSON을 자바 객체로 변환하여 실제로 사용할 수 있게 한다.
내가 직면한 문제는 JSON 데이터를 서버에서 받아 역직렬화하는 과정에서 발생한 거였다. JSON 포맷에 맞지 않는 데이터를 객체로 변환하려다 보니 오류가 발생했고, 그 해결 과정에서 JSON 직렬화/역직렬화의 중요성을 깨닫게 되었다.
▶문제 상황
▽ PaymentRequestDto.이 클래스는 결제 정보를 담고 있는 객체이고, 이를 JSON으로 직렬화하거나 역직렬화해야 했다.
public class PaymentRequestDto {
private String impUid;
private String merchantUid;
private String payMethod;
private String buyerEmail;
private String buyerTel;
// 기본 생성자, getter 생략
}
클라이언트에서 JSON 형태로 데이터를 받아 이 객체로 역직렬화하는 과정에서 문제가 발생했다. 문제가 발생한 JSON 데이터는 다음과 같다.
{
"impUid": "imp_1234567890",
"merchantUid": "order_1234",
"payMethod": "card",
"buyerEmail": "buyer@example.com",
"buyerTel": 1234567890
}
→ 여기서 buyerTel 필드가 숫자형(int)으로 전달되었는데, 이 필드는 원래 문자열(String)로 선언되어 있었기 때문에 오류가 발생했다.
▶ 에러 로그
다음은 역직렬화 과정에서 발생한 에러 로그이다.
com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize value of type `java.lang.String` from Integer value (token `JsonToken.VALUE_NUMBER_INT`)
at [Source: (String)"{"impUid":"imp_1234567890","merchantUid":"order_1234","payMethod":"card","buyerEmail":"buyer@example.com","buyerTel":1234567890}"; line: 1, column: 141] (through reference chain: PaymentRequestDto["buyerTel"])
→ 이 에러는 buyerTel 필드가 숫자형으로 전달되었지만, 클래스에서는 문자열로 정의되어 있기 때문에 발생한 문제였다. 이로 인해 JSON 데이터를 객체로 변환하는 역직렬화 과정에서 오류가 발생했다.
▶문제 해결 과정
이 문제를 해결하기 위해 두 가지 방법을 생각해 보았다.
▷ JSON 데이터를 수정: 클라이언트에서 buyerTel 필드를 문자열로 보내도록 JSON 데이터를 수정한다. JSON 데이터를 다음과 같이 수정할 수 있다.이 방법은 데이터를 전송하는 쪽에서 문제를 해결하는 방법이다. 하지만 클라이언트 측에서 수정이 어려운 상황이 있을 수 있기 때문에 두 번째 방법도 고려해야 했다.
{
"impUid": "imp_1234567890",
"merchantUid": "order_1234",
"payMethod": "card",
"buyerEmail": "buyer@example.com",
"buyerTel": "1234567890"
}
▷ 자바 클래스에서 데이터 타입 유연하게 처리: 자바에서 숫자형 데이터도 문자열로 처리할 수 있도록 buyerTel 필드를 Object 타입으로 선언하고, 변환 과정을 추가하는 방법! 이 방법을 통해 역직렬화 과정에서 숫자형이나 문자열 모두를 받아 처리할 수 있도록 했다.
public class PaymentRequestDto {
private String impUid;
private String merchantUid;
private String payMethod;
private String buyerEmail;
private Object buyerTel;
public String getBuyerTel() {
return buyerTel.toString(); // 숫자형도 문자열로 변환
}
// 기타 getter 생략
}
▶직렬화와 역직렬화 라이브러리
나는 Jackson 라이브러리를 사용하고 있다. Jackson은 자바 객체와 JSON 간의 직렬화 및 역직렬화를 손쉽게 처리할 수 있는 라이브러리다. Jackson을 사용하여 아래와 같이 객체를 JSON으로 직렬화할 수 있다.
ObjectMapper objectMapper = new ObjectMapper();
PaymentRequestDto paymentRequestDto = new PaymentRequestDto();
paymentRequestDto.setImpUid("imp_1234567890");
paymentRequestDto.setMerchantUid("order_1234");
// 객체를 JSON 문자열로 변환
String jsonString = objectMapper.writeValueAsString(paymentRequestDto);
System.out.println(jsonString);
→ Jackson은 자동으로 객체의 필드와 매칭하여 JSON으로 변환해 주며, 역직렬화 역시 간단하게 처리할 수 있다.
String jsonInput = "{ \"impUid\": \"imp_1234567890\", \"merchantUid\": \"order_1234\" }";
PaymentRequestDto paymentRequestDto = objectMapper.readValue(jsonInput, PaymentRequestDto.class);
System.out.println(paymentRequestDto.getImpUid());
▶직렬화/역직렬화의 중요성
JSON 직렬화/역직렬화는 클라이언트와 서버 간의 데이터 교환에서 필수적인 과정이다. 특히 다양한 데이터 유형을 처리할 때, 데이터 형식이 일치하지 않으면 오류가 발생할 수 있기 때문에 신경 써야 한다. 직렬화와 역직렬화를 할 때는 데이터 타입에 유의해야 하고, 특히 자바의 객체 필드 타입과 JSON 데이터 형식이 일치하지 않는 경우가 발생할 수 있다. 이를 해결하기 위해서는 JSON 데이터를 처리할 때 유연성을 제공하거나, 데이터를 전송하는 클라이언트 측에서 문제를 해결해야 한다.
▶결론
자바 객체와 JSON 간의 변환 과정에서 발생할 수 있는 데이터 타입 불일치 문제를 해결하는 방법을 배우고, 이를 통해 클라이언트와 서버 간의 데이터 교환을 원활하게 처리할 수 있게 되었다. 그리고 직렬화/역직렬화 과정에서 발생할 수 있는 문제에 대해 더 유의해야한다.
'개발Article' 카테고리의 다른 글
[TIL]20240917 Singleton! (0) | 2024.09.18 |
---|---|
[TIL]20240916 결제 연동 흐름의 보완점 (7) | 2024.09.16 |
[TIL]20240914 Gradle과 Maven의 차이점 (0) | 2024.09.15 |
[TIL]20240913 내부DB & 그냥DB 그리고 동기화 (1) | 2024.09.14 |
[TIL]20240912 리플렉션(Reflection)과 자바철학 (0) | 2024.09.12 |