[Java] 직렬화(Serialization)

예림·2024년 6월 13일
2

java

목록 보기
5/5

게시판 만들기를 하면서 페이지네이션에 직렬화 인터페이스를 적용하면 더 수월하게 구현할 수 있을 것 같아 정리해본다.

Serilizable

: 직렬화

public interface Serializable{
}
  • 메소드가 하나도 없는 이 인터페이스, 언제 필요할까?
    • 생성한 객체를 파일로 저장할 때
    • 저장한 객체를 읽어야 할 때
    • 다른 서버에서 생성한 객체를 받을 때

즉, class를 생성한 후에 해당 class다른 파일에서 읽거나 쓰려면,

혹은 다른 서버에서 보내거나 받기 위해서 반드시 Serializable 인터페이스가 필요하다 !


직렬화란 ?

자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 JVM에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술

변환된 데이터를 다시 객체로 변환하는 기술(역직렬화)


자바 직렬화는 어떻게(how) 사용할 수 있나요?

자바 직렬화 조건

자바 기본(primitive) 타입과 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;
        }
    
        // Getter 생략
    
        @Override
        public String toString() {
            return String.format("Member{name='%s', email='%s', age='%s'}", name, email, age);
        }
}

직렬화 방법

자바 직렬화를 하기 위해 java.io.ObjectOutputStream 객체를 이용한다.

Member member = new Member("이예림", "dkdldb9867@gmail.com", 24);
    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));
}
  • 객체를 직렬화하여 바이트 배열(byte []) 형태로 변환

역직렬화 조건

  • 직렬화 대상이 된 객체의 클래스가 클래스 패스에 존재해야 하며 import 되어 있어야 한다.
    • 중요한 점은 직렬화와 역직렬화를 진행하는 시스템이 서로 다를 수 있다는 것을 반드시 고려해야 한다는 것
  • 자바 직렬화 대상 객체는 동일한 serialVersionUID 를 가지고 있어야 한다.
        private static final long serialVersionUID = 1L;
    사실 이 부분은 자동 생성해주기 때문에 반드시 기술해야 되는 필수는 아니다.

역직렬화 예제

// 직렬화 예제에서 생성된 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);
    }
}

자바의 직렬화 왜(why) 사용되나요?

문자열 형태의 직렬화 방법

: 직접 데이터를 문자열 형태로 확인 가능한 직렬화 방법

범용적인 API나 데이터를 변환하여 추출할 때 많이 사용된다.

표형태의 다량의 데이터를 직렬화시 CSV가 많이 쓰이고 구조적인 데이터는 이전에는 XML을 많이 사용했으며 최근에는 JSON형태를 많이 사용하고 되고 있다.

  • CSV
    • 데이터를 표현하는 가장 많이 사용되는 방법 중 하나로 콤마(,) 기준으로 데이터를 구분하는 방법
        이예림,dkdldb9867@gmail.com
      
    • 자바에서 사용방법
        Member member = new Member("이예림", "dkdldb9867@gmail.com", 24);
        // member객체를 csv로 변환 
        String csv = String.format("%s,%s,%d",member.getName(), member.getEmail(), member.getAge()); 
        System.out.println(csv);
      예제에서는 문자열로 단순히 변경했지만, 자바에서는 Apache Commons CSVopencsv 등의 라이브러리 등을 이용할 수 있다
  • JSON
    • 최근에 가장 많이 사용하는 포맷으로 자바스크립트(ECMAScript)에서 쉽게 사용 가능하고, 다른 데이터 포맷 방식에 비해 오버헤드가 적기 때문에 많이 사용된다.
        { 
          name: "이예림",
          email: "dkdldb9867@gmail.com",
          age: 24
        }
    • 자바에서 사용방법
        Member member = new Member("이예림", "dkdldb9867@gmail.com", 24);
        // member객체를 json으로 변환 
        String json = String.format(
                "{\"name\":\"%s\",\"email\":\"%s\",\"age\":%d}",
                member.getName(), member.getEmail(), member.getAge());
        System.out.println(json);
      JSON도 물론 이렇게 직접 문자열을 만들일은 거의 없다. 자바에서는 JacksonGSON 등의 라이브러리를 이용해서 변환할 수 있다.

CSV 같은 경우 표 형태의 데이터에서 많이 사용되며, JSON 같은 경우는 구조적인 데이터를 전달하는 API 시스템 등에서 많이 사용하고 있다.


참고자료

profile
백엔드 개발하는 사람

0개의 댓글