티스토리 뷰
KH 정보교육원 [ Java ]
KH 130일차 - Spring ( Java <-> JSON Serialize / Deserialize ) (****)
monimoni 2022. 9. 1. 15:101. JSON으로 변환되는 형태 (***)
1 ) 평범한 자바객체(POJO) : { .. }
2 ) 배열 객체 : [ .. ]
3 ) List 컬렉션 : [ .. ]
4 ) Set 컬렉션 : [ .. ]
5 ) Map 컬렉션 : [ .. ]
6 ) 중첩된 자바객체( 자바 객체 안에 자바 객체 ) : { .. }
[ 1. Java -> JSON로 변환(Serialize) / JSON -> Java 객체로 역변환(Deserialize) ] (***)
[ 1 - 1. pom.xml에 디펜던시 추가 ]
더보기
[ + 코드 보기 ]
<!-- 변환 라이브러리 -->
<!-- (1) 자바객체를 직렬화(Serialize)하여 JSON / XML 로 변환 -->
<!-- (2) JSON / XML를 역직렬화(De-serialize)하여 자바객체로 변환 -->
<!-- Java 객체를 JSON으로 변환시켜 준다. -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
<!-- Java 객체를 XML로 변환해 준다. -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.13.3</version>
</dependency>
<!-- Java 객체를 JSON으로 변환 -->
<!-- 위의 2개는 스프링 프레임워크가 사용하고, gson은 우리가 사용한다. -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.1</version>
</dependency>
<!-- genson -->
<dependency>
<groupId>com.owlike</groupId>
<artifactId>genson</artifactId>
<version>1.6</version>
</dependency>
<!-- json-io -->
<dependency>
<groupId>com.cedarsoftware</groupId>
<artifactId>json-io</artifactId>
<version>4.13.0</version>
</dependency>
[ 1 - 2. domain 생성 ( JSON을 보고 VO를 생성해야 한다. ) ] (***)
더보기
[ + 코드 보기 ]
package org.zerock.myapp.domain;
import lombok.Value;
@Value
public class Bar {
private Integer id;
private String name;
} // end class
package org.zerock.myapp.domain;
import lombok.Value;
@Value
public class Foo {
private Integer id;
private String name;
} // end class
[ 1 - 3. gson 테스트 ]
더보기
[ + 코드 보기 ]
package org.zerock.myapp.gson;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Timeout;
import org.zerock.myapp.domain.Bar;
import org.zerock.myapp.domain.Foo;
import com.google.gson.Gson;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class GsonTests {
// @Disabled
@Test
@Order(1)
@DisplayName("1. testSerialize")
@Timeout(value = 3, unit = TimeUnit.SECONDS)
void testSerialize() {
log.trace("testSerialize() invoked.");
// + Java 객체 -> JSON 문자열로 변환 ( Serialize )
Foo obj = new Foo(100, "pyramid");
log.info("\t + obj : {}", obj);
// + obj : Foo(id=100, name=pyramid)
Gson gson = new Gson();
String json = gson.toJson(obj);
log.info("\t + Java - > json : {}",json);
// + Java - > json : {"id":100,"name":"pyramid"}
// + 이처럼 Java의 필드명이 키가 된다.
// + Serialize는 gson.toJson(object)처럼 to로 시작하고
// + deserialize는 fromJson처럼 from으로 시작한다.
} // testSerialize
// ===================================================
// @Disabled
@Test
@Order(2)
@DisplayName("2. testDeserialize")
@Timeout(value = 3, unit = TimeUnit.SECONDS)
void testDeSerialize() {
log.trace("testDeSerialize() invoked.");
// + JSON 문자열 -> Java 객체로 변환 ( Deserialize )
String json = "{\"id\":100,\"name\":\"pyramid\"}"; // OK ( 자바는 ""만 문자열로 받기에, 이클립스에서 자동으로 변환 )
// String json = "{ 'id' :100, 'name' : 'pyramid' }"; // OK ( ''로 문자열을 받아도 잘 역변환되고 있다. )
Gson gson = new Gson();
Foo obj = gson.<Foo>fromJson(json, Foo.class); // OK
Bar obj2 = gson.<Bar>fromJson(json, Bar.class); // OK ( Bar도 Foo와 같은 필드를 가지고 있기에, OK! )
// + .fromJson(String json, Clazz 객체)
log.info("\t + obj : {}", obj);
// + obj : Foo(id=100, name=pyramid)
log.info("\t + obj.getId : {}", obj.getId());
// + obj.getId : 100
log.info("\t + obj.getName : {}", obj.getName());
// + obj.getName : pyramid
} // testDeSerialize
// ===================================================
} // end class
[ 1 - 4. Vo Class 수정 -> Genson의 경우에는 기본 Constructor 및 Getter/Setter를 요구한다. ] (**)
[ + @Value에서 @Data로 변경해야 한다. ]
더보기
[ + 코드 보기 ]
package org.zerock.myapp.domain;
import lombok.Data;
// @Value
@Data // ( Genson 라이브러리는 기본 생성자를 요구한다. )
public class Foo {
private Integer id;
private String name;
} // end class
[ 1 - 5. Genson 테스트 ]
더보기
[ + 코드 보기 ]
package org.zerock.myapp.genson;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Timeout;
import org.zerock.myapp.domain.Bar;
import org.zerock.myapp.domain.Foo;
import com.owlike.genson.Genson;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class GensonTests {
// @Disabled
@Test
@Order(1)
@DisplayName("1. testSerialize")
@Timeout(value = 3, unit = TimeUnit.SECONDS)
void testSerialize() {
log.trace("testSerialize() invoked.");
Foo obj = new Foo();
obj.setId(300);
obj.setName("momomomo");
log.info("\t + 1. obj : {}", obj);
// + 1. obj : Foo(id=300, name=momomomo)
Genson genson = new Genson();
String json = genson.serialize(obj);
log.info("\t + 2. serialize json : {}", json);
// + 2. serialize json : {"id":300,"name":"momomomo"}
// + genson의 경우 serialize / deserialize를 통해서 변환 / 역변환이 가능하다.
} // testSerialize
// ===================================================
// @Disabled
@Test
@Order(2)
@DisplayName("2. testDeSerialize")
@Timeout(value = 3, unit = TimeUnit.SECONDS)
void testDeSerialize() {
log.trace("testDeSerialize() invoked.");
// + Genson 라이브러리를 이용한 DeSerialize하기 위해서는,
// + 자바 객체가 기본 생성자와 Getter/Setter를 가지고 있어야만 한다. (***)
// + 그렇기에 @Value가 아닌 @Data를 사용해줘야만 한다.
String json = "{\"id\":300,\"name\":\"momomomo\"}";
// String json = "{ 'id' :100, 'name' : 'pyramid' }"; // xx : Genson에서는 ''로 바꾼것도 불가능하다.
Genson genson = new Genson();
Foo foo = genson.<Foo>deserialize(json, Foo.class);
log.info("\t + 3. deserialize java : {}", foo);
// + 3. deserialize java : Foo(id=300, name=momomomo)
} // testDeSerialize
// ===================================================
} // end class
[ 1 - 6. JasonIO 테스트 ]
더보기
[ + 코드 보기 ]
package org.zerock.myapp.jsonio;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Timeout;
import org.zerock.myapp.domain.Foo;
import com.cedarsoftware.util.io.JsonReader;
import com.cedarsoftware.util.io.JsonWriter;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JsonIoTests {
// @Disabled
@Test
@Order(1)
@DisplayName("1. testSerialize")
@Timeout(value = 3, unit = TimeUnit.SECONDS)
void testSerialize() {
log.trace("testSerialize() invoked.");
// + 자바 객체를 JSON으로 변환
Foo obj = new Foo();
obj.setId(300);
obj.setName("momomom");
log.info("\t + 1. obj : {}", obj);
// + 1. obj : Foo(id=300, name=momomom)
String json = JsonWriter.objectToJson(obj);
log.info("\t + 2. json : {}", json);
// + 2. json : {"@type":"org.zerock.myapp.domain.Foo","id":300,"name":"momomom"}
// + JasonIO는 type도 반환하고 있다.
// + type을 알려줌으로써 이 type으로 DeSerialize하게 하고 있다.
// + JasonIO는 다른 라이브러리와 다르게 JsonWriter.objectToJson을 통해 Serialize하고 있다.
} // testSerialize
// ===================================================
// @Disabled
@Test
@Order(2)
@DisplayName("2. testDeSerialize")
@Timeout(value = 3, unit = TimeUnit.SECONDS)
void testDeSerialize() {
log.trace("testDeSerialize() invoked.");
// + JSON 문자열 -> Java 객체로 변환 ( Deserialize )
// + genson과 JsonIo에서는 ESCAPE 문자를 적용한 json을 사용해야 한다. (***)
// + JsonIo에서는 JsonReader.jsonToJava를 통해 DeSerialize한다.
// + JsonIo에서는 type도 사용한다.
String json = "{\"@type\":\"org.zerock.myapp.domain.Foo\",\"id\":300,\"name\":\"momomom\"}";
log.info("\t + 3. json : {}",json);
// + 3. json : {"@type":"org.zerock.myapp.domain.Foo","id":300,"name":"momomom"}
Foo obj = (Foo) JsonReader.jsonToJava(json);
log.info("\t + 4. obj : {}", obj);
// + 4. obj : Foo(id=300, name=momomom)
log.info("\t + 5. obj.getId : {}", obj.getId());
// + 5. obj.getId : 300
log.info("\t + 6. obj.getName : {}", obj.getName());
// + 6. obj.getName : momomom
} // testDeSerialize
// ===================================================
} // end class
[ 1 - 7. Jackson 테스트 ]
더보기
[ + 코드 보기 ]
package org.zerock.myapp.jackson;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Timeout;
import org.zerock.myapp.domain.Bar;
import org.zerock.myapp.domain.Foo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
@Log4j2
@NoArgsConstructor
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JacksonTests {
// @Disabled
@Test
@Order(1)
@DisplayName("1. testSerialize")
@Timeout(value = 3, unit = TimeUnit.SECONDS)
void testSerialize() throws JsonProcessingException {
log.trace("testSerialize() invoked.");
// + 자바 객체를 JSON으로 변환
Foo obj = new Foo();
obj.setId(300);
obj.setName("momomom");
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(obj);
// + Jackson에서는 writeValueAsString으로 Serialize한다.
log.info("\t + 1. json : {}", json);
// + 1. json : {"id":300,"name":"momomom"}
} // testSerialize
// ===================================================
// @Disabled
@Test
@Order(2)
@DisplayName("2. testDeSerialize")
@Timeout(value = 3, unit = TimeUnit.SECONDS)
void testDeSerialize() throws JsonMappingException, JsonProcessingException {
log.trace("testDeSerialize() invoked.");
// + JSON 문자열 -> Java 객체로 변환 ( Deserialize )
String json = "{\"id\":300,\"name\":\"momomom\"}";
// + GSON 라이브러리 외에서는 위와 같이 모두 탈출문자를 사용하여 표현해야 한다.
log.info("\t + 2. json : {}", json);
// + 2. json : {"id":300,"name":"momomom"}
ObjectMapper mapper = new ObjectMapper();
Foo obj = mapper.readValue(json, Foo.class); // OK
// Bar obj2 = mapper.readValue(json, Bar.class); // xx : @Data가 아니어서 예외발생
log.info("\t + 3. obj : {}", obj);
// + 3. obj : Foo(id=300, name=momomom)
log.info("\t + 4. obj.getId : {}", obj.getId());
// + 4. obj.getId : 300
log.info("\t + 5. obj.getName : {}", obj.getName());
// + 5. obj.getName : momomom
} // testDeSerialize
// ===================================================
} // end class
728x90
'KH 정보교육원 [ Java ]' 카테고리의 다른 글
KH 132일차 - gitignore (0) | 2022.09.05 |
---|---|
KH 131일차 - Git / Git Hub (0) | 2022.09.02 |
KH 129일차 - Spring ( Open API / Dom4j / jaxen ) (*****) (0) | 2022.08.31 |
KH 128일차 - Spring ( 트랜잭션 / 패스워드 암호화 / open API ) (******) (0) | 2022.08.30 |
KH 127일차 - Spring( AOP 2 / 트랜잭션[미완성] ) (******) (0) | 2022.08.29 |
댓글