티스토리 뷰

반응형

직렬화 기술 이해

자바 직렬화란?

[cs 직렬화] 컴퓨터 과학, 그 중에서 데이터 저장소(data storage )의 맥락에서 직렬화는 객체의 상태 혹은 데이터 구조를 기록할 수 있는 포맷 혹은 데이터 (예를 들면 파일 또는 메모리 버퍼 또는 네트워크 연결링크를 통해 전송될 수 있는 형태)로 변환하며, 나중에 동일 혹은 다른 컴퓨터 환경에서 재구성할 수있게끔 하는 절차이다.

  • 자바의 직렬화는 자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록, 바이트 형태로 데이터를 변환하는 기술, 그리고 바이트 변환 데이터를 다시 객체로 변환하는 기술(역 직렬화)을 아울러 이야기합니다.
  • 시스템적으로 JVM 에 메모리에 상주하고 있는(메모리, 힙) 객체 데이터를 바이트 형태로 변환하는 기술과 바이트 형태의 데이터를 객체로 변환해서 JVM 에 상주시키는 형태를 이야기 합니다.

자바 직렬화를 왜 쓰는가!

직렬화(CSV, JSON, 프로토콜 버퍼 등)시스템 고유의 특성과 관계 없이 대부분의 시스템 데이터 교환시 많이 이용됩니다.

하지만, 자바 직렬화형태의 데이터 교환은 자바 시스템 간의 데이터 교환에 용이합니다.

  • 자바 직렬화의 장점
    • 자바 시스템 개발에 최적화 되어, 복잡한 데이터 구조의 클래스 객체도 무리 없이 직렬화 가능합니다. 데이터 타입이 자동으로 맞춰줘서 역직렬화시, 기존 객체처럼 바로 사용가능합니다.

자바 직렬화의 사용처

https://woowabros.github.io/experience/2017/10/17/java-serialize.html ( 상세한 자바 직렬화의 사용서가 나옵니다.)

  • 서블릿 세션 ( 세션 대부분이 자바의 직렬화를 지원합니다.)
  • 캐시
  • 자바 RMI (클라이언트에서 서버 함수를 사용하는 것으로 추정. 아직 잘 모르겠음.)

https://m.blog.naver.com/PostView.nhn?blogId=fltltmxjs&logNo=80188194209&proxyReferer=https:%2F%2Fwww.google.com%2F

직렬화 적용 분야

  • 파일 저장소(File Storage)
    • 프로그램 실행 중에 생성된 데이터를 영구 저장소(파일 시스템)등에 저장한 후, 이후에 프로그램이 다시 실행됐을때, 저장된 데이터를 메모리 상에 객체 형태로 복구해 사용한다.
  • 네트워크 통신(Network Communication)
    • 네트워크상에 떨어져있는 프로그램 간 데이터를 주고받기 위해, 데이터를 직렬화한 후, 패킷에 담아 전송한다.
  • 데이터베이스(Database)
    • 복잡한 형태의 객체를 데이터베이스에 저장할 때, 직렬화한 문자열 형태로 테이블 컬럼에 저장하기도 한다.
  • 웹환경(Web Environment)
    • 웹 서버에서 브러우저(클라이언트)로 구조화한 데이터를 전송할 때, 직렬화한 후, (JSON 형식 등) 전달하는 방식이 많이 사용되고 있다.

직렬화 데이터 형식

  • Binary
    • 메모리에 저장된 데이터를 최소한의 가공 혹
  • JSON(JavaScript Object Notation)
    • 텍스트 형식이므로 사람과 기계 모두 읽기 가능하다. 다양한 프로그래밍 언어에서 읽고 쓸 수 있어 널리 사용된다.
  • XML
    • 텍스트 형식이며, json에 비해 복잡하다. json 대비 가지는 장점은, 스키마를 적용할 수 있고, 무결성 검사가 가능하다.
  • YAML
    • xml 에 비해 사람이 읽고 쓰기 쉽도록 고안된 마크업언어이다. 문법이 상대적으로 단순하고, 가독성이 높게 설계된다.

자바의 직렬화 사용법

자바에서 java.io.Serirializable 인터페이스를 상속받은 객체는 직렬화를 할 수 있는 기본 조건을 가집니다.
package me.whiteship.serialize;
import 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.io.ObjectOutputStream 을 이용합니다.

  private static String getSerializedString() {
    Member member = new Member("길재은", "rha3122@naver.com", 25);
    byte[] serializedMember;
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
      try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
        oos.writeObject(member);
        // serializedMember -> 직렬화된 member 객체
        serializedMember = baos.toByteArray();
      }
      // 바이트 배열로 생성된 직렬화 데이터를 base64 로 변환
      return Base64.getEncoder().encodeToString(serializedMember);
      // > 객체를 직렬화하여 바이트 배열 (byte[]) 형태로 변환
    } catch (IOException e) {
      e.printStackTrace();
      return "fail";
    }
  }

역직렬화 조건
  • 직렬화된 대상의 객체의 클래스가 클래스패스에 존재해야하고, import 되어 있어야한다.

    • 중요한 점은 직렬화와 역직렬화를 진행하는 시스템이 서로 다를 수 있음을 고려해야한다.
  • 자바의 직렬화 대상의 객체는 동일한 serialVersionUID를 가지고 있어야한다.

    private static final long serialVersionUID = 1L;

serialVersionUID 는 직렬화에 사용되는 고유 아이디인데, 선언하지 않으면 JVM에서 디폴트로 자동 생성된다.

따라서 선언하지 않아도 동작하는데 문제는 없지만, 불안하기 때문에 JAVA에서는 명시적으로 serialVersionUID를 선언할 것을 적극 권장하고 있다.

출처: https://hyeonstorage.tistory.com/253 [개발이 하고 싶어요]

역직렬화 예제
// 직렬화 예제에서 생성된 base64 데이터
  private static void deSerializedString(String base64Member) {
    byte[] serializedMember = Base64.getDecoder().decode(base64Member);
    try (ByteArrayInputStream bais = new ByteArrayInputStream(serializedMember)) {
      try (ObjectInputStream ois = new ObjectInputStream(bais)) {
        // 역직렬화괸 Member 객체를 읽어온다.
        Object objMember = ois.readObject();
        Member member = (Member) objMember;
        System.out.println(member);
      }
    } catch (IOException | ClassNotFoundException e) {
      e.printStackTrace();
    }
  }

자바 직렬화를 왜 사용할까?

문자열 형태의 직려화 방법
  • 직접 데이터를 문자열 형태로 확인 가능한 직렬화 방법입니다. 범용적인 api 나 데이터를 변환해 추출할 때 많이 사용합니다.
  • 표형태의 다량의 데이터 직렬화시 csv 가 많이 쓰이고, 구조적인 데이터는 이전에 xml 을 많이 사용했으며, 최근에는 json 형태를 가장 많이 사용하고 있습니가. 배민 블로그의 예시로 있던, csv 와 json 만 잠깐 들고 가겠습니다.
CSV
  • 데이터를 표현하는 가장 많이 사용되는 방법 중 하나로, 콤마기준으로 데이터를 구분합니다.
길재은,rha3122@naver.com,25    
  • 자바에서 사용법
Member member = new Member("길재은", "rha3122@naver.com",25);
// member 객체를 csv로 변환
String csv  = String.format("%s,%s,%d", member.getName(), member.getEmail(), member.getAget());
System.out.println(csv);

JSON

  • 최근에 가장 많이 사용하는 포맷으로 자바스크립트(ECMAScript)에서 쉽게 사용 가능하고, 다른 데이터 포맷 방식에 비해 오버헤드가 적기 때문에 때문에 인기가 많습니다.

이진 직렬화 방법

데이터 변환 및 전송 속도에 최적화해서 별도의 직렬화 방법을 제시하는 구조입니다. 직렬화뿐만 아니라,다른 얘기도 하지만, 직렬화 부분만 이야기 하겠습니다. 종류로는 (Protocol Buffer, Apache Avro) 등이 있습니다.

  • Protocol Buffer

    • 프로토콜 버퍼는 구글에서 제안한 플랫폼 독립적인 데이터 직렬화 플랫폼입니다.
      Member member = Member.newBuilder()
          .setAge(25)
          .setName("길재은")
          .setEmail("rha3122@naver.com")
          .build();
      ByteArrayOutputStream baos = new ByteArrayOutputStream()
      member.writeTo(baos);
      // 프로토콜 버퍼 직렬화된 데이터
      byte[] serializedMember = baos.toByteArray();    

참고 링크

https://woowabros.github.io/experience/2017/10/17/java-serialize.html

https://woowabros.github.io/experience/2017/10/17/java-serialize2.html

https://www2.slideshare.net/sunnykwak90/java-serialization-46382579?qid=e7c2f288-705c-4d8a-a358-e05b05621111&v=&b=&from_search=1

https://hyeonstorage.tistory.com/253

반응형

'스프링, 자바' 카테고리의 다른 글

jsp 데이터베이스 사용 간단 정리본  (0) 2021.01.26
Lambda, Stream : wip  (0) 2021.01.24
NIO 기반 입출력 및 네트워킹  (0) 2021.01.23
jsp 와 세션  (0) 2021.01.19
jsp 와 쿠키  (0) 2021.01.19
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
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 31
글 보관함