개발 기록
> [Java] 직렬화 (Serializable) 에 대해서 3. Java 객체 직렬화/역직렬화 방법(Json, YAML, binary ) - GSON, YAML Bean, Protocol Buffers 등 본문
> [Java] 직렬화 (Serializable) 에 대해서 3. Java 객체 직렬화/역직렬화 방법(Json, YAML, binary ) - GSON, YAML Bean, Protocol Buffers 등
1z 2020. 12. 14. 10:52
Java 객체에 대한 다양한 직렬화(객체-> 바이트 스트림으로 변환) 접근 방식
① CSV
② JSON
③ YAML
④ 이진데이터
* 데이터 편집에는 YAML 이 적합하다. 반면에 바이너리 형식은 텍스트 형식보다 빠르므로. 애플리케이션에 속도가 중요한 경우 Apache Thrift 및 Google 프로토콜 버퍼를 사용하기 좋다. 둘 다 XML이나 JSON 형식보다 더 작고 빠르다.
■
1. CSV
CSV 는 표 형태의 데이터에서 많이 사용되며 데이터를 표현하는 가장 많이 사용되는 방법 중 하나로 콤마(,) 기준으로 데이터를 구분하는 방법이다. (ex. 홍길동, user@email.com, 40)
Member member = new Member("kimuser", "user@email.com", 25);
// member 객체를 csv로 변환
String csv = String.format("%s,%s,%d",member.getName(), member.getEmail(), member.getAge());
★ 자바에서는 Apache Commons CSV, opencsv 등의 라이브러리 등을 이용할 수 있다.
■
2. JSON
JSON 는 구조적인 데이터를 전달하는 API 시스템 등에서 많이 사용한다. 다른 데이터 포맷 방식에 비해 오버헤드가 적다.
★ 자바에서는 Jackson, GSON 등의 라이브러리 등을 이용할 수 있다.
(1) Gson
☞ Google의 Gson은 Java 개체를 JSON 표현으로 직렬화 및 역직렬화하는 데 사용되는 라이브러리로 toJson() 및 fromJson() 메서드를 제공한다.
☞ Gson 기능
- 컬렉션, 일반 및 중첩 클래스를 처리할 수 있니다.
- Gson을 사용하면 전체 프로세스를 제어할 수 있도록 사용자 정의 직렬 변환기 및/또는 역직렬 변환기를 사용할 수 있다.
- 소스 코드에 액세스할 수 없는 클래스의 인스턴스를 역직렬화할 수 있다.
- 클래스 파일이 다른 버전으로 수정된 경우 @Since 주석과 setVersion() 메서드를 사용하여 버전 관리를 할 수 있다.
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
▶ ex. User 개체를 " gson_user.json" 파일로 직렬화
String filePath = "src/test/resources/protocols/gson_user.json";
// 직렬화
Writer writer = new FileWriter(filePath);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
gson.toJson(user, writer);
// 역직렬화
Gson gson = new GsonBuilder().setPrettyPrinting().create();
User deserializedUser = gson.fromJson(new FileReader(filePath), User.class);
(2) Jackson API
ObjectMapper 클래스 에 속하는 writeValue(), readValue() 메소드를 사용하여 직렬화/ 역직렬화 한다.
☞ Jackson 특징
- Java용 JSON 직렬화 라이브러리
- ObjectMapper 사용
- the highly customizable serialization and deserialization process
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.12.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.4</version>
</dependency>
String filePath = "src/test/resources/protocols/jackson_user.json";
// 직렬화 (jackson_user.json 파일 작성)
File file = new File(filePath);
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(file, user);
// 역직렬화
User deserializedUser = mapper.readValue(new File(filePath), User.class);
■
3. 이진 직렬화 방법
데이터 변환 및 전송 속도에 최적화하여 별도의 직렬화 방법을 제시하는 구조이다. 바이너리 전송 형식으로 즉, 데이터가 바이너리로 전송된다.
☞ 장점
- 언어와 플랫폼에 의존하지 않는다.
- 공간과 대역폭을 덜 차지 하므로 전송 속도를 향상 시킨다.
- 새 버전이 이전 데이터를 읽을 수 있고 그 반대로도 읽을 수 있도록 이전 버전 및 이후 버전과의 호환성을 모두 지원한다.
★ Protocol Buffer, Apache Avro, Apache Thrift 등 의 라이브러리를 이용할 수 있다.
(1) Google Protocol Buffer
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.17.3</version>
</dependency>
▶ user.proto 문서 생성
message Member {
required string name = 1;
optional string email = 2;
required int32 age = 3;
}
▶ 위의 user.proto 문서를 프로토콜 버퍼 컴파일러를 이용해서 변환한다.
: 자바로 변환하게 되면 프로토콜 버퍼 형태의 Member 클래스가 생성되며, 자바 직렬화와 다른 점은 데이터 스펙을 표현하기 위한 문서가 존재한다는 것이다. 나머지는 같다.
Member member = Member.newBuilder()
.setAge(10)
.setName("홍길동")
.setEmail("user@email.com")
.build();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
member.writeTo(baos);
// 프로토콜 버퍼 직렬화된 데이터
byte[] serializedMember = baos.toByteArray();
▶ mergeFrom() 메서드를 사용하여 파일에서 해당 데이터를 로드하고 다시 User 개체로 역직렬화할 수 있다.
■
4. YAML
★ Jackson API, SnakeYAML, YAML Bean 등 의 라이브러리를 이용할 수 있다.
* SnakeYAML의 경우 Java 객체를 YAML 문서로 직렬화하거나 그 반대로 직렬화하는 고급 API를 제공한다. Object, String , List 및 Map 과 같은 Java 구조를 구문 분석할 수 있다.
(1) YAML Bean
<dependency>
<groupId>com.esotericsoftware.yamlbeans</groupId>
<artifactId>yamlbeans</artifactId>
<version>1.15</version>
</dependency>
▶YamlWriter 클래스의 write () 메소드를 사용하여 Java 객체를 YAML로 직렬화 한다. public field 와 Bean의 getter 메소드를 인식하여 이를 자동으로 처리한다.
▶반대로 YamlReader 클래스의 read () 메서드는 YAML 문서를 읽고 Java 객체로 역직렬화한다.
// 직렬화
YamlWriter writer = new YamlWriter(new FileWriter(filePath));
writer.write(userMap()); // Map<String, User>
writer.close();
// 역직렬화
YamlReader reader = new YamlReader(new FileReader(filePath));
Object object = reader.read();
Map<String, User> deserializedUsers = (Map<String, User>) object;
참고
https://techblog.woowahan.com/2550/
https://www.baeldung.com/java-serialization-approaches
'JAVA' 카테고리의 다른 글
| > [Java] hashcode() & equals() 메서드 재정의와 관계성 (0) | 2023.07.18 |
|---|---|
| > [Java] 람다 (Lambda) 개념과 사용 (0) | 2022.11.11 |
| > [Java] 직렬화 (Serializable) 에 대해서 2. 의문점과 답변 정리 (0) | 2020.10.02 |
| > [Java] 직렬화 (Serializable) 에 대해서 1. 개념과 구현 (0) | 2020.09.22 |
| >[Java] static, final, 상수 개념과 사용 (0) | 2020.07.19 |