데이터 직렬화와 역직렬화
데이터 직렬화(Serialization)와 역직렬화(Deserialization)
- 데이터 직렬화 (Serialization)
정의: 객체의 상태(데이터와 필드 값 등)를 저장하거나 네트워크로 전송하기 위해 바이트 스트림으로 변환하는 과정.
목적:
객체를 파일, 데이터베이스 등에 저장.
네트워크를 통해 객체를 전송.
직렬화된 데이터는 일반적으로 이진 데이터(Binary Data) 또는 텍스트 형식(JSON, XML 등)으로 표현됩니다. - 데이터 역직렬화 (Deserialization)
정의: 직렬화된 데이터를 다시 객체로 복원하는 과정.
목적:
저장된 데이터를 읽어와서 객체로 재구성.
네트워크를 통해 받은 데이터를 객체로 변환.
Java에서 직렬화와 역직렬화 - 직렬화
Java에서는 java.io.Serializable 인터페이스를 사용하여 객체를 직렬화할 수 있습니다. 이 인터페이스는 구현할 메서드가 없는 마커 인터페이스로, 객체가 직렬화 가능함을 표시합니다.
코드 예제: 직렬화
java
import java.io.*;
class Person implements Serializable {
private static final long serialVersionUID = 1L; // 클래스 버전을 지정
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}}
public class SerializationExample {
public static void main(String[] args) {
Person person = new Person("Alice", 25);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
oos.writeObject(person); // 객체를 파일로 직렬화
System.out.println("Serialization done.");
} catch (IOException e) {
e.printStackTrace();
}
}}
2. 역직렬화
코드 예제: 역직렬화
java
Copy code
import java.io.*;
public class DeserializationExample {
public static void main(String[] args) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
Person person = (Person) ois.readObject(); // 파일에서 객체로 복원
System.out.println("Deserialization done.");
System.out.println(person);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
3. 직렬화의 특징
serialVersionUID: 직렬화된 객체가 역직렬화될 때 클래스의 호환성을 검증하기 위해 사용됩니다.
클래스 구조가 변경되었을 경우, 호환되지 않는 serialVersionUID를 가진 객체는 역직렬화 중 오류를 발생시킵니다.
명시적으로 정의하지 않으면 Java가 자동으로 생성합니다.
transient 키워드: 특정 필드를 직렬화하지 않으려면 transient 키워드를 사용합니다.
java
Copy code
class Person implements Serializable {
transient String password; // 직렬화 제외
}
JSON, XML 기반 직렬화
Java에서는 이진 데이터 대신 JSON, XML 형식을 사용하여 데이터를 직렬화/역직렬화할 수 있습니다. 이를 위해 Gson, Jackson, XML Parsers와 같은 라이브러리를 자주 사용합니다.
JSON 직렬화 예제 (Gson 사용)
java
Copy code
import com.google.gson.Gson;
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}}
public class JsonExample {
public static void main(String[] args) {
Gson gson = new Gson();
// 직렬화
Person person = new Person("Alice", 25);
String json = gson.toJson(person);
System.out.println("Serialized JSON: " + json);
// 역직렬화
Person deserializedPerson = gson.fromJson(json, Person.class);
System.out.println("Deserialized Object: " + deserializedPerson);
}}
직렬화와 역직렬화의 실제 사용 사례
네트워크 통신:
REST API에서 JSON 또는 XML 데이터를 전송.
RMI(Remote Method Invocation)에서 객체 전달.
파일 저장:
애플리케이션 상태 저장.
데이터베이스와의 통합 없이 간단한 데이터 저장.
캐싱:
객체를 직렬화하여 디스크나 메모리에 저장해 빠르게 복원.
분산 시스템:
클라우드 환경에서 서로 다른 서비스 간 데이터 교환.
주의점
보안:
역직렬화는 직렬화된 데이터가 신뢰할 수 있는 소스에서 왔는지 확인해야 합니다.
악의적인 데이터가 포함될 경우, 역직렬화 과정에서 실행 가능한 객체가 생성될 수 있습니다.
효율성:
직렬화는 데이터 크기를 증가시킬 수 있습니다.
JSON 또는 Protocol Buffers와 같은 더 가벼운 데이터 포맷이 대안이 될 수 있습니다.
호환성:
클래스 구조 변경 시 serialVersionUID를 적절히 관리해야 이전 데이터를 복원할 수 있습니다.