직렬화와 역직렬화

직렬화는 다차원의 데이터를 네트워크로 다른 곳에 보내거나 파일로 저장하기 위해서 1차원의 데이터로 변환하는 것을 이야기합니다. 역질려화는 이와 반대되는 작업이죠.

실제로 직렬화는 spring에서도 json 파일로 정보를 보내기 위해서 직렬화를 많이 사용합니다. 사실 spring에서는 그저 serializable 마커 인터페이스를 넣어주는 것 만으로 알아서 직렬화와 역직렬화를 해주기 때문에 다른 작업을 할 필요가 없죠. 하지만 우리는 공부를 하는 입장이기 때문에 실제로 직렬화와 역직렬화를 해보는 것 까지 수행해봅시다.

import java.io.Serializable;

public class Message implements Serializable {
    private long id;
    private String msg;

    public Message(long id, String msg){
        this.id = id;
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "Message{" +
                "id=" + id +
                ", msg='" + msg + '\\'' +
                '}';
    }
}

우선 위와 같이 클래스를 작성하고 직렬화 인터페이스도 붙였습니다.

아까도 이야기 했지만 직렬화 인터페이스는 마커인터페이스라서 딱히 아무것도 구현하지 않아도됩니다.

그저 표시일 뿐이죠.

public class SerializeTest {

    @Test
    void 직렬화와(){
        Message msg = new Message(0, "hello world!");

        byte[] bitStream = new byte[0];
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
                oos.writeObject(msg); // oos 에 직렬화의 대상인 member 객체를 전달
                bitStream = baos.toByteArray();
                // toByteArray() 메서드를 통해 직렬화 수행 ( Object -> Byte )
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(Base64.getEncoder().encodeToString(bitStream));
    }
    @Test
    void 역직렬화(){

        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();
                Message msg = (Message) objectMember;
                System.out.println(msg);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

직렬화를 하고 그 결과를 역직렬화 String에 넣어주면 정상적으로 작동하고 내가 만들었던 결과가 잘 출력되는 것을 알 수 있습니다.

지금까지 직렬화와 역직렬화에 대해서 봤는데 이 내용에 대해서는 사실 조심해야할 점이 있습니다. 그건 역직렬화를 할 때 정말로 옳은 데이터를 사용하는지 검증할 방법이 없기 때문입니다. 따라서 이부분에 대해서 잘 구현하지 않으면 악의적인 의도를 가지고 보안을 뚫는다던지 공격을 할 수 있습니다. 물론 우리가 보안 관련 진로를 원한다면 이 부분에 대해서 자세히 공부를 해야하겠지만 필자는 그 분야에 관심이 없기 때문에 그저 직렬화/역직렬화가 잘 구현되어 있는 프레임 워크를 사용할 것입니다.

String Constant Pool

string pool이라고도 하는데 이건 무엇이며 이건 왜 있는 걸까요?

자바는 객체를 heap영역에 저장합니다. 그런데 string의 경우에는 일반적인 객체를 만드는 과정으로 생성되면 자바에서는 그다지 성능이 좋지 않습니다. 오버헤드가 발생할 수 있기 때문이죠 이를 방지하기 위해서 string pool이라는 것이 생겨났습니다. 결국에는 한번 사용한 string을 재사용하자가 string pool의 목적입니다.