# 직렬화와 역직렬화

- 직렬화 : 자바 시스템 내부에서 사용되는 객체, 데이터를 외부에서도 사용할 수 있도록 바이트 형태로 변환하는 작업
- 역직렬화 : 직렬화된 데이터를 받는 쪽에서 다시 객체 형태로 변환하는 작업
# 직렬화 조건
- Primitive 타입은 그냥 가능
- Reference 타입처럼 주소값을 가진 객체들은 바이트로 변환하기 위해 Serializable 인터페이스를 구현해야 함
# 직렬화 예시
@Entity
@AllArgsConstructor
@toString
public class Post implements Serializable {
private static final long serialVersionUID = 1L;
private String title;
private String content;
// ...
}
- serialVersionUID 생성
- serialVersionUID : 객체의 스키마(포맷)를 식별하는 버전 관리 도구(이 바이트 데이터가 현재 클래스 구조와 호환되는가?)
Post post = new Post("제목", "내용");
byte[] serializedPost;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(post);
serializedPost = baos.toByteArray();
}
}
- ObjectOutputStream으로 직렬화를 수행
- Byte로 변환된 값을 저장
# 역직렬화 예시
try (ByteArrayInputStream bais = new ByteArrayInputStream(serializedPost)) {
try (ObjectInputStream ois = new ObjectInputStream(bais)) {
Object objectPost = ois.readObject();
Post post = (Post) objectPost;
}
}
- ObjectInputStream로 역직렬화를 수행
- Byte의 값을 다시 객체로 저장
# 스프링에서는?
- 스프링의 spring-web에서는 Java 객체를 JSON으로 직렬화해서 응답을 내려줌
implementation 'org.springframework.boot:spring-boot-starter-web'
- 위 의존성에 포함되어 있는 Jackson 라이브러리의 ObjectMapper를 사용해 자동으로 자바 객체를 직렬화 / 역직렬화함
- 실제로는 Jackson2HttpMessageConverter가 ObjectMapper를 가지고 컨버팅하는 작업을 수행
// AbstractJackson2HttpMessageConverter.java, writeInternal()
// ObjectMapper 선택
ObjectMapper objectMapper = selectObjectMapper(clazz, contentType);
// JsonGenerator 생성 (JSON 출력 스트림)
JsonGenerator generator = objectMapper.getFactory().createGenerator(outputStream, encoding);
// ObjectWriter 생성 (직렬화 설정 적용)
ObjectWriter objectWriter = objectMapper.writer();
// 실제 직렬화 수행
objectWriter.writeValue(generator, value);
# 실제 스프링 직렬화 과정
@RestController 메서드 반환
↓
DispatcherServlet
↓
HttpMessageConverter 선택
↓
MappingJackson2HttpMessageConverter
↓
writeInternal() ← 위 코드
↓
ObjectMapper.writeValue()
↓
JSON 문자열 → HTTP Response Body