본문 바로가기
Java

Java_객체의 직렬화와 역직렬화

by 유서담 2023. 11. 26.

직렬화(Serialization)

  • 객체를 스트림을 통해서 전송가능한 상태로 바꾸는 것이다.

 

직렬화 클래스

 

  • ObjectOutputStream
    • void writeObject(Object target) : 대상객체를 직렬화한다.

 

역직렬화(Deserialization)

  • 스트림을 통해서 전송받은 데이터로 객체를 복원하는 것이다.

 

역직렬화 클래스

 

  • ObjectInputStream
    • Object readObject() : 객체를 복원한다.

 

 

직렬화/역직렬화 가능 객체의 필수 조건

 

  • 대상객체는 java.io.Serializable 인터페이스를 구현한 객체
  • 대상객체가 포함하고 있는 객체도 java.io.Serializable 인터페이스를 구현한 객체
  • 직렬화대상에서 제외시키기 해당 필드에 transient 키워드를 추가한다.

 

개발시 주의사항

 

  • 웹개발자는 직렬화/역직렬화화 관련된 코드를 직접 작성하는 경우는 극히 드물다.
    • (단, 서버(웹서버, 채팅서버, 게임서버)개발자의 경우에만 직렬화/역직렬화 관련 코드를 작성할 수도 있다.)
  • 직렬화 가능한 객체가 되게 하는 방법
    • 대상객체도 java.io.Serializable 인터페이스 구현
    • 대상객체에 포함된 객체도 java.io.Serializable 인터페이스 구현
  • 직렬화 대상에서 제외시키는 방법
    • 해당 필드에 transient 키워드 추가
  • serialVersionUID 정의하는 방법
    • 이클립스의 serialVersionUID 생성기능 사용
  • serialVersionUID
    • 스트림 고유 식별자(stream unique identifier)
    • 직렬화 가능한 모든 클래스는 고유 식별자를 가진다.
      • static final long serialVersionUID를 명시적으로 정의하지 않으면, 컴파일시에 자동으로 생성된다.
      • 직렬화한 후에 클래스를 변경했다면 고유 식별자값이 변경된다. 역직렬화할 때 InvalidClassException이 발생한다.
    • serialVersionUID를 명시적으로 정의하면 직렬화 후 클래스가 변경되어도 역직렬화할 때 문제가 발생하지 않는다.

 

 

마샬링(Marshalling)과 언마샬링(UnMarshalling)

 

  • 마샬링은 주로 서로 다른 시스템 혹은 프로그램간의 데이터 이동에 사용된다.
  • 마샬링은 객체(데이터)를 전송하기 위해서 상호호환성이 높은 형태로 변경하는 것을 말한다.
    • 객체의 데이터를 XML로 변경하기
    • 객체의 데이터를 JSON으로 변경하기
    • 객체의 데이터를 csv로 변경하기
  • 언마샬링은 마샬링된 데이터를 객체로 변환하는 것이다.
  • 언마샬링은 전송받은 텍스트를 객체로 변환하면 텍스트일 때보다 데이터를 다루기가 쉬워진다.
    • XML은 Document로 변환하는 것
    • JSON은 JSONObject로 변환하는 것

 

마샬링과 언마샬링을 하는 이유

 

마샬링을 하는 이유 :  전송 및 출력때에 객체보다는 텍스트(일반적으로)가 전송 및 출력때 편하기 때문

언마샬링을 하는 이유 : 조작 및 분석때에 텍스트(일반적으로)보다는 객체가 조작 및 분석때 편하기 때문

 


 

직렬화/역직렬화 예시 코드

 

public class ObjectOutputApp1 {

	public static void main(String[] args) throws Exception{
		
		/*
		 * ObjectOutputStream
		 * 	- 객체를 직렬화해서 스트림으로 전송한다
		 * 	- ObjectOutputStream의 writeObject(Object obj)는
		 * 	  지정된 객체를 직렬화해서 연결된 스트림으로 내보낸다
		 */
		
		// 객체를 직렬화하기 - 객체를 스트림으로 출력해보기
		User user = new User(100, "고길동", "qwer1234", "gildong@gmail.con");
		
		String path = "src/io5/user.obj";
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path));
		
		// 객체를 직렬화한다
		out.writeObject(user);
		
		out.close();
	}
}

 

직렬화해서 전송하는 코드

 

public class ObjectInputApp1 {

	public static void main(String[] args)throws Exception {
		
		String path = "src/io5/user.obj";
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream(path));
		
		// 역직렬화
		User user = (User)in.readObject();
		
		System.out.println(user.getNo());
		System.out.println(user.getId());
		System.out.println(user.getPassword());
		System.out.println(user.getEmail());
	}
}

 

역직렬화 코드

public class User implements Serializable {

	
	private static final long serialVersionUID = -3137364349244922093L;
	private int no;
	private String id;
	private transient String password;
	private String email;
	
	public User(int no, String id, String password, String email) {
		
		this.no = no;
		this.id = id;
		this.password = password;
		this.email = email;
	}

	public int getNo() {
		return no;
	}

	public String getId() {
		return id;
	}

	public String getPassword() {
		return password;
	}

	public String getEmail() {
		return email;
	}
	
	
	
}

 

user 객체 생성 및 getter 코드

 


 

'Java' 카테고리의 다른 글

Java_네트워크, I/O  (0) 2023.11.29
Java_I/O(입출력)  (1) 2023.11.27
Java_예외처리  (0) 2023.11.22
Java_Map, Comparable  (2) 2023.11.21
Java_Collection Framework, Iterator  (0) 2023.11.21