데이터 직렬화
: 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트 형태로 데이터 변환하는 기술
데이터 역직렬화
: 바이트로 변환된 데이터를 다시 객체로 변환하는 기술
직렬화란?
메모리를 디스크에 저장하거나, 네트워크 통신에 사용하기 위한 형식으로 변환하는 것이다.
자바 직렬화는 자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용
할 수 있도록 바이트 형태로 데이터 변환하는 기술을 뜻한다.
직렬화의 장점
•
객체 내용을 입출력형식에 구애받지 않고 객체를 파일에 저장함으로써 영속성을 제공한다.
•
객체를 네트워크를 통해 손쉽게 교환할 수 있다.
직렬화 사용
메모리에만 상주되어 있는 객체 데이터를 그대로 영속화(persist)가 필요할 때 사용된다. 시스템이
종료되더라도 없어지지 않는 장점을 가지며 영속화된 데이터이기 때문에 네트워크로 전송도 가능하다.
직렬화 조건
직렬화를 하기 위한 조건 → 객체가 직렬화 가능한 클래스의 인스턴스여야 한다.
직렬화 가능한 클래스로 만드는 방법 → java.io.Serializable인터페이스 구현(implements)하도록 선언하면 된다.
/**
* 직렬화 가능한 클래스로 만들기 위해
* java.io.Serializable 인터페이스를 구현한다.
*/
public class Member implements Serializable {
private String name;
private String email;
private int age;
public Member(String name, String email, int age) {
this.name = name;
this.email = email;
this.age = age;
}
@Override
public String toString() {
return String.format("Member{name='%s', email='%s', age='%s'}", name, email, age);
}
}
Java
복사
객체를 직렬화할 때 특정 멤버 필드를 제외하고 싶다면 멤버 변수에 transient키워드를 선언하면 된다.
public class Member implements Serializable {
private String name;
private transient String email;
private int age;
Java
복사
직렬화 방법
•
java.io.ObjectOutputStream 클래스를 사용하여 직렬화를 진행
public static void main(String[] args){
Member member = new Member("김배민", "deliverykim@baemin.com", 25);
byte[] serializedMember;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(member);
// serializedMember -> 직렬화된 member 객체
serializedMember = baos.toByteArray();
}
}
// 바이트 배열로 생성된 직렬화 데이터를 base64로 변환
System.out.println(Base64.getEncoder().encodeToString(serializedMember));
}
Java
복사
역직렬화 조건
•
직렬화 대상이 된 객체의 클래스가 클래스 패스에 존재해야 하며 import 되어 있어야 한다.
•
자바 직렬화 대상 객체는 동일한 SerialVersionUID를 가지고 있어야 한다.
역직렬화 방법
•
java.io.ObjectInputStream 클래스를 사용하여 역직렬화를 진행
public static void main(String[] args){
// 직렬화 예제에서 생성된 base64 데이터
String base64Member = "...생략";
byte[] serializedMember = Base64.getDecoder().decode(base64Member);
try (ByteArrayInputStream bais = new ByteArrayInputStream(serializedMember)) {
try (ObjectInputStream ois = new ObjectInputStream(bais)) {
// 역직렬화된 Member 객체를 읽어온다.
Object objectMember = ois.readObject();
Member member = (Member) objectMember;
System.out.println(member);
}
}
}
Java
복사
SerialVersionUID
•
직렬화 및 역직렬화 할때 필요한 정보
•
데이터를 직렬화 한 다음 해당 데이터의 원본 클래스에 속성을 추가하고, 이전에 직렬화된 데이터를 역직렬화 하면 java.io.InvalidCalssException 예외가 발생
•
직렬화 타입 체크가 엄격 String -> StringBuilder, int -> long 변경시 역직렬화 과정에서 Exception이 발생
직렬화하면 내부에서 자동으로 SerialVersionUID라는 고유의 번호를 생성하여 관리한다.
이 UID는 직렬화와 역직렬화 할 때 중요한 역할을 한다. 이 값이 맞는지 확인 후 처리하기 때문이다.
만약 SerialVersionUID 값이 맞지 않는다면 오류를 출력한다.