일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- OS
- Spring
- MySQL
- c언어
- design pattern
- 자료구조
- IT
- Java
- C
- JPA
- mongoDB
- 운영체제
- 컴퓨터구조
- 파이썬
- 네트워크
- Algorithm
- 자바
- react
- 백준
- spring webflux
- JavaScript
- 알고리즘
- Heap
- Galera Cluster
- 디자인 패턴
- Kafka
- Proxy
- MSA
- redis
- Data Structure
Archives
- Today
- Total
시냅스
Java 코드로 알아보는 직렬화와 역직렬화 본문
자바 직렬화 (Java Serialization)
- 자바 객체를 바이트 스트림으로 변환하여 파일이나 네트워크 상에서 전송 가능하도록 만드는 것
- 자바 객체는 주소 값을 가지고 있고 이는 프로세스가 새로 실행될 때 마다 변하는 값이다.
- 프로세스를 새로 실행했을 때 해당 객체에 대한 주소가 같을 거라는 보장이 없다.
- 따라서 객체(혹은 레퍼런스 타입)에 대한 데이터를 외부에 저장하고 싶다면 직렬화가 필요하다.
- 직렬화된 객체는 다시 역직렬화(Deserialization)하여 객체로 변환될 수 있다.
- 역직렬화를 할 때에는 몇가지 조건이 필요하다.
- 직렬화 대상의 클래스가 class path 에 존재하며 import 되어 있어야 한다.
- 동일한 버전 (serialVersionId) 를 유지해야 한다.
- 만약 serialVersionId을 선언하지 않았다면 내부 클래스 구조 정보를 이용하여 자동으로 생성된 해시 값이 할당된다.
- 따라서 멤버 변수 등이 추가/삭제 된다면 자동으로 버전은 바뀌게 된다.
- 역직렬화를 할 때에는 몇가지 조건이 필요하다.
- 객체를 전송 가능한 형태로 만들어줌으로써 객체를 쉽게 공유할 수 있다.
- Serializable 인터페이스를 구현하여 변환 가능하다.
- Serializable 인터페이스는 마커 인터페이스로 표시하기만 한다.
- 사용처
- 객체를 파일이나 데이터베이스에 저장하고 싶을 때
- 객체를 네트워크를 통해 전송하고 싶을 때 (Servlet Session)
- 객체를 메모리에 캐시하여 재사용하고 싶을 때 (Redis 등)
- 객체를 복제하고 싶을 때
직렬화의 종류
- Text 기반 직렬화
- 객체를 text 형태로 변환하여 저장하는 방식
- CSV, XML, JSON 등
- 직렬화된 데이터를 읽고 디버깅 하기 용이하다.
- 사람이 읽을 수 있을 수 있는 형태로 저장되므로 다른 시스템과의 호환성이 높다.
- 다만 데이터 크기가 크고 직렬화/역직렬화 속도가 느리다.
- 2진(Binary) 기반 직렬화
- 효율적인 저장 및 전송이 가능하다.
- 다만 직렬화된 데이터를 사람이 확인하기 어렵다.
직렬화 코드 예제
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
- 예제로 사용할 Person 객체이다.
2진 (binary) 기반
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person p1 = new Person("lilt", 30);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
// Person 객체를 직렬화하여 objectOutputStream에 쓰기
objectOutputStream.writeObject(p1);
// 직렬화된 데이터를 바이트 배열로 변환
byte[] bytes = byteArrayOutputStream.toByteArray();
// 직렬화된 데이터 출력을 위해 InputStream 사용
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
// 역직렬화된 Person 객체를 읽어온다.
Person deserialized = (Person) ois.readObject();
System.out.println(deserialized.getName()); // lilt
System.out.println(deserialized.getAge()); // 30
ois.close();
bais.close();
objectOutputStream.close();
byteArrayOutputStream.close();
}
}
- 2진 기반 직렬화로 outputstream을 사용하여 byte 배열로 생성한다.
- 이후 역직렬화를 위해 inputstream을 사용하여 간단하게 객체를 확인할 수 있다.
text 기반
public class Main {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
Person person = new Person("lilt", 30);
String json = objectMapper.writeValueAsString(person);
System.out.println(json); // {"name":"lilt","age":30}
Person deserialized = objectMapper.readValue(json, Person.class);
System.out.println(deserialized.getName());
System.out.println(deserialized.getAge());
}
}
- text 기반은 json 을 예시로 한다.
- 또한 jackson 라이브러리를 사용하여 간편하게 구현할 수 있다.
- 역직렬화를 할 때에는 밸류와 원하는 클래스를 파라미터로 넘겨 원하는 객체를 얻어올 수 있다.
- 다만 역직렬화를 할 때에는 프록시 등의 이유로 기본 생성자를 필요로 한다.
'Java, Spring' 카테고리의 다른 글
Java 코드로 보는 Connection 관련 timeout 에러 정리 (0) | 2023.03.01 |
---|---|
Java 코드와 예제로 보는 Thread Dump 활용 방법 (0) | 2023.03.01 |
Visual VM과 nGrinder를 사용한 모니터링과 부하 테스트 (0) | 2023.02.19 |
nGrinder 설명과 사용법 정리 (5) | 2023.02.19 |
JMeter 설명과 사용법 정리 (0) | 2023.02.19 |
Comments