차근차근/JAVA JSP

Serialize 직렬화

예쁜꽃이피었으면 2021. 12. 7. 14:50

결론

자바 직렬화는 장점이 많은 기술입니다만 단점도 많습니다.
문제는 이 기술의 단점은 보완하기 힘든 형태로 되어 있기 때문에 사용 시 제약이 많습니다. 그래서 이 글을 적는 저는 직렬화를 사용할 때에는 아래와 같은 규칙을 지키려고 합니다.

  1. 외부 저장소로 저장되는 데이터는 짧은 만료시간의 데이터를 제외하고 자바 직렬화를 사용을 지양합니다.
  2. 역직렬화시 반드시 예외가 생긴다는 것을 생각하고 개발합니다.
  3. 자주 변경되는 비즈니스적인 데이터를 자바 직렬화을 사용하지 않습니다.
  4. 긴 만료 시간을 가지는 데이터는 JSON 등 다른 포맷을 사용하여 저장합니다.
더보기
https://ko.wikipedia.org/wiki/%EC%A7%81%EB%A0%AC%ED%99%94
직렬화(直列化) 또는 시리얼라이제이션(serialization)은 컴퓨터 과학의 데이터 스토리지 문맥에서 데이터 구조나 오브젝트 상태를 동일하거나 다른 컴퓨터 환경에 저장(이를테면 파일이나 메모리 버퍼에서, 또는 네트워크 연결 링크 간 전송)하고 나중에 재구성할 수 있는 포맷으로 변환하는 과정이다.

https://terms.naver.com/entry.naver?docId=836830&cid=50376&categoryId=50376
직렬화하다
:공간적으로 동시에 존재하는 상태로 표현되어 있는 데이터를 이것에 대응하는 직렬(시리얼)인 상태로 존재하도록 변환한다라는 의미가 있다. 정지화한다(staticize)와 대비된다.

 

직렬화(Serialize)

- 자바 시스템 내부에서 사용되는 Object또는 Data를 외부의 자바 시스템에서도 사용할 수 있도록 byte형태로 데이터를 변환하는 기술

- JVM의 메모리에 상주(힙/스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술

 

역직렬화(Deserialize)

- byte로 변환된 Data를 원래대로 Object나 Data로 변환하는 기술

- 직렬화된 바이트 형태의 데이터를 객채로 변환해서 JVM으로 상주시키는 형태


직렬화 조건

- 기본형 타입(int, char, String, short, double, long, byte..)은 직렬화 가능

- Serializable인터페이스를 구현한 객체여야 한다.

- transient가 사용된 멤버는 전송되지 않는다.

더보기
transient
transient라는 예약어는 Serializable과 떨어질 수 없는 관계
transient private int bookOrder;​

 

SerialDTO 클래스에 transient 라는 예약어를 추가한 후에 다시 객체를 파일에 저장하고 읽어오는 코드를 실행해보겠습니다.
Write Success
SerialDTO{booName='God of Java', bookOrder=0, bestSeller=true, soldPerDay=100}​
그러면 객체를 생성할 때 bookOrder에 1을 넣었지만 결과에는 0이 나오는 것을 볼 수 있습니다.
0이 나오는 이유가 무엇일까요?
 
객체를 저장하거나, 다른 JVM으로 보낼 때, transient 예약어를 사용하여 선언한 변수는 Serializable의 대상에서 제외됩니다.
그러면 뭐하러 이것을 사용하나 싶을 수 있지만, 패스워드와 같이 보안상 중요한 변수나 꼭 저장해야 할 필요가 없는 변수에 대해서는 transient를 사용할 수 있습니다.

- 생성자나 메소드는 직렬화 대상에 속하지 않는다.

 

자바의 직렬화는 왜 할까?

- 복잡한 데이터 구조의 클래스의 객체라도 직렬화 기본 조건만 지키면 큰 작업없이 바로 직렬화, 역직렬화가 가능

- 데이터 타입이 자동으로 맞춰지기 때문에 관련 부분은 큰 신경을 쓰지 않아도 된다.

 

직렬화는 언제 어디서 사용될까?

- JVM의 메모리에서만 상주되어 있는 객체 데이터를 그대로 영속화(Persistence)가 필요할 때 사용한다.

더보기
영속화 : 어떤 일이 중도에 끊기거나 바뀌지 않고 지속됨.
≒ 영속성 

- 시스템이 종료되어도 없어지지 않는 장점이 있고 영속화된 데이터이기 때문에 네트워크로 전송도 가능하다.

- 필요할 때 직렬화된 객체 데이터를 가져와서 역직렬화하여 객체를 바로 사용할 수 있게 된다. 

 

1) 서블릿 세션(Servlet Session)

- 서블릿 기반의 was(톰캣,웹로직:WebLogic 등)들은 대부분, 세션의 자바 직렬화를 지원하고 있다.

- 단순히 세션을 서블릿 메모리 위에서 운용한다면 직렬화가 필요하지 않다.

그러나, 파일로 저장하거나 세션 클러스터링, DB를 저장하는 옵션 등을 선택하게 되면 세션 자체가 직렬화되어 저장되어 전달됨. => 그래서 세션에 필요한 객체는 java.io.Serializable인터페이스를 implements해두는 것을 추천한다.

2) 캐시(Cache)

- 자바 시스템에서 퍼포먼스을 위해 캐시라이브러리(Ehcache,Redis..) 시스템을 많이 이용한다.

- 캐시할 부분을 자바 직렬화된 데이터를 저장해서 사용한다. (물론 자바 직렬화만 이용하여 캐시를 저장하는 것은 아니다.)

3) 자바 RMI(Remote Method Invocation)

- 원격 시스템간의 메시지 교환을 위해서 사용하는 자바에서 지원하는 기술

- 보통은 원격의 시스템과의 통신을 위해서 IP와 포트를 이용해서 소켓통신을 해야 하지만, RMI는 그 부분을 추상화하여 원격에 있는 시스템의 메소드를 로컬 시스템의 메서드인 것처럼 호출할 수 있다.

 

자바 직렬화 왜 사용될까?( 자바에서 CSV, JSON을 사용하면 되지 자바 직렬화를 써야 하는 이유가 있나?)

- 답은 목적에 따라 적절하게 써야 한다.

더보기

문자열 형태의 직렬화 방법

직접 데이터를 문자열 형태로 확인 가능한 직렬화 방법입니다. 범용적인 API나 데이터를 변환하여 추출할 때 많이 사용됩니다.
표형태의 다량의 데이터를 직렬화시 CSV가 많이 쓰이고 구조적인 데이터는 이전에는 XML을 많이 사용했으며 최근에는 JSON형태를 많이 사용하고 되고 있습니다.
여기서는 CSV와 JSON만 살펴보겠습니다.

  • CSV
    • 데이터를 표현하는 가장 많이 사용되는 방법 중 하나로 콤마(,) 기준으로 데이터를 구분하는 방법입니다.
    • 자바에서 사용방법예제에서는 문자열로 단순히 변경했습니다.
      자바에서는 Apache Commons CSV, opencsv 등의 라이브러리 등을 이용할 수 있습니다.
  • JSON
    • 최근에 가장 많이 사용하는 포맷으로 자바스크립트(ECMAScript)에서 쉽게 사용 가능하고,
      다른 데이터 포맷 방식에 비해 오버헤드가 적기 때문에 때문에 인기가 많습니다.
    • 자바에서 사용방법JSON도 물론 이렇게 직접 문자열을 만들일은 거의 없습니다.
      자바에서는 Jackson, GSON 등의 라이브러리를 이용해서 변환할 수 있습니다.
위에 언급한 CSV, JSON 형태의 직렬화는 익숙한 사람이 많을 것입니다.
CSV 같은 경우 표 형태의 데이터에서 많이 사용되며, JSON 같은 경우는 구조적인 데이터를 전달하는 API 시스템 등에서 많이 사용하고 있기 때문입니다.

이진 직렬화 방법

데이터 변환 및 전송 속도에 최적화하여 별도의 직렬화 방법을 제시하는 구조입니다.
직렬화뿐만 아니라 전송 방법에 대한 부분도 이야기하고 있지만 여기서는 직렬화 부분만 이야기하겠습니다.
종류로는 Protocol Buffer(이하 프로토콜버퍼) Apache Avro 등이 있습니다.
기타
지면 관계상 프로토콜 버퍼만 한번 살펴보겠습니다. (살펴보면 알겠지만 직렬화하기 위한 패턴은 비슷합니다.)

  • Protocol Buffer(이하 프로토콜 버퍼)
    • 프로토콜 버퍼는 구글에서 제안한 플랫폼 독립적인 데이터 직렬화 플랫폼입니다.
    • 자바에서 사용방법
      프로토콜 버퍼는 특정 언어 또는 플랫폼에 종속되지 않는 방법을 구현하기 위해 직렬화 하기 위한 데이터를 표현하기 위한 문서가 따로 있습니다.

      이렇게 기술된 member.proto 문서를 프로토콜 버퍼 컴파일러를 이용해서 개발하기 원하는 언어(여기서는 자바)로 변환해야 합니다.
      (프로토콜 버퍼 컴파일러는 별도로 설치하거나 Gradle, Maven등 의 빌드 도구를 이용하면 됩니다.)
      자바로 변환하게 되면 프로토콜 버퍼 형태의 Member 클래스가 생성됩니다.

      자바 직렬화와 다른 점은 데이터 스펙을 표현하기 위한 문서가 존재하는 부분입니다. 그 이외에는 대부분 동일합니다.
그 외 여러가지 직렬화 방법이 있는 있지만 여기서 다 다루지는 못하지만 직렬화 관련 좋은 포스팅이 있어서 추천드립니다. 링크
그럼 다시 왜 자바 직렬화를 사용하는지 이야기해보겠습니다. CSV, JSON, 프로토콜 버퍼 등은 시스템의 고유 특성과 상관없는 대부분의 시스템에서의 데이터 교환 시 많이 사용됩니다.
하지만 "자바 직렬화 형태의 데이터 교환은 자바 시스템 간의 데이터 교환을 위해서 존재한다."고 생각하시면 됩니다.

자바 직렬화의 장점 

- 자바 직렬화는 자바 시스템에서 개발에 최적화 되어있다.

- 복잡한 데이터 구조를 가진 클래스의 객체라도 직렬화 기본 조건만 맞으면 큰 작업없이 바로 직렬화/역직렬화 가능

- 데이터 타입이 자동을 맞춰지기 때문에 관련 부분을 크게 신경쓰지 않아도 된다. + 역직렬화 시 기존 객체처럼 바로 사용할 수 있으니 개발자입장에서 편리


[참조]

https://nesoy.github.io/articles/2018-04/Java-Serialize

 

Java의 직렬화(Serialize)란?

 

nesoy.github.io

 

https://techblog.woowahan.com/2550/

 

자바 직렬화, 그것이 알고싶다. 훑어보기편 | 우아한형제들 기술블로그

{{item.name}} 자바의 직렬화 기술에 대한 대한 이야기입니다. 간단한 질문과 답변 형태로 자바 직렬화에 대한 간단한 설명과 직접 프로젝트를 진행하면서 겪은 경험에 대해 이야기해보려 합니다.

techblog.woowahan.com

https://j.mearie.org/post/122845365013/serialization

 

직렬화

며칠 전 해커뉴스에서 “인터넷은 디버깅 모드로 돌아가고 있다"는 글을 보았다. 아, 원래 글을 읽을 필요는 없다. 글의 내용이라는 게 JSON이나 XML은 텍스트 포맷인데 바이너리 포맷보다 오버헤

j.mearie.org

https://techblog.woowahan.com/2551/

 

자바 직렬화, 그것이 알고싶다. 실무편 | 우아한형제들 기술블로그

{{item.name}} 자바의 직렬화 기술에 대한 대한 두 번째 이야기입니다. 실제 자바 직렬화를 실무에 적용해보면서 주의해야 할 부분에 대해 이야기해보려고합니다. 자바 직렬화 실제 업무에서 사용

techblog.woowahan.com

자바 직렬화, 그것이 알고싶다. 실무편 댓글 중에...
serialize 시에 호환성을 해치지 않으면서 어디까지 수정이 가능한지 궁금하신분은 스펙에 versioning 문서 하단을 읽어보시면 도움 되실듯 합니다.(http://docs.oracle.com/.../serialization/spec/version.html)
참고로 필드 지우는게 오류는 발생하지 않았다고 하셨지만, 스펙에서는 구버전에서 신버전 클래스를 읽을 경우에 문제를 일으킬수 있다고 비호환적이라고 해놨네요 (예 - https://stackoverflow.com/.../delete-field-from-old-ava...
)
반응형