Java 객체(object)를 JSON 표현식으로 변환하는 API
Gson 은 Java 객체를 JSON 표현식으로 변환할 수 있게 하는 Java 라이브러리 이다. 물론 JSON 표현식 형태의 스트링을 Java 객체로 변환 또한 가능하다. 주로 사용할 클래스는 Gson 이고 그냥 new Gson() 으로 객체생성하면 된다. GsonBuilder 클래스도 있으나 다양한 셋팅을 해서 Gson 객체를 생성할 때나 사용한다. Gson 객체는 상태값 같은 것을 가지고 있지 않으므로 다수의 Json 직렬화(serialization)와 역직렬화(deserialization) 처리시에 계속 재사용해도 된다.
밑의 예제는 https://sites.google.com/site/gson/gson-user-guide 사이트의 예제이므로 참고하시기 바란다.
그 중 많이 쓸거 같은 예제들만 한번 골라서 알아보자.
1. 자바의 기본자료형 예시 (Primitives Examples). 어렵지 않게 변환할 수 있다.
// (Serialization) Gson gson = new Gson(); gson.toJson(1); // ==> prints 1 gson.toJson("abcd"); // ==> prints "abcd" gson.toJson(new Long(10)); // ==> prints 10 int[] values = { 1 }; gson.toJson(values); // ==> prints [1] // (Deserialization) int one = gson.fromJson("1", int.class); Integer one = gson.fromJson("1", Integer.class); Long one = gson.fromJson("1", Long.class); Boolean false = gson.fromJson("false", Boolean.class); String str = gson.fromJson("\"abc\"", String.class); String anotherStr = gson.fromJson("[\"abc\"]", String.class);
2. 자바의 객체 변환 예시. 아래와 같은 클래스가 있다고 가정하자.
class BagOfPrimitives { private int value1 = 1; private String value2 = "abc"; private transient int value3 = 3; BagOfPrimitives() { // no-args constructor } }
JSON 표현식으로 변환을 해보면,
// (Serialization) BagOfPrimitives obj = new BagOfPrimitives(); Gson gson = new Gson(); String json = gson.toJson(obj); // ==> json is {"value1":1,"value2":"abc"}
객체변환시에 다음과 같은 특징이 있다.
1. private 접근자의 필드들도 변환이 가능하다.
2. 특정 어노테이션 사용할 필요없이 기본적으로 현재 클래스의 모든 필드들은 직렬화 및 역직렬화 대상이 된다.
3. transient 구분자를 사용하면 직렬화 및 역직렬화 처리에서 제외된다.
4. 직렬화시 null 값인 필드는 자동 제외 된다. 역직렬화시에 JSON 에 일치하는 필드가 없으면 null로 셋팅된다.
5. Synthetic 필드는 직렬화 역직렬화 대상에서 제외된다.
6. 내부클래스관한 이야기가 있는데.. 너무 복잡하다. 잘 사용안하므로 skip. 궁금하신분은 원문 참고하세요.
3. 배열 예시. 배열은 [ ] 로 표현되어 나오며, 어렵지 않게 상호간에 변환된다.
Gson gson = new Gson(); int[] ints = {1, 2, 3, 4, 5}; String[] strings = {"abc", "def", "ghi"}; // (Serialization) gson.toJson(ints); // ==> prints [1,2,3,4,5] gson.toJson(strings); // ==> prints ["abc", "def", "ghi"] // (Deserialization) int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class); // ==> ints2 will be same as ints
4. 컬렉션(Collections) 예시. 배열과 같이 [ ] 로 표현되며, 하지만 역직렬화할때 좀 다른 걸 알 수 있다.
Gson gson = new Gson(); Collection<Integer> ints = Lists.immutableList(1,2,3,4,5); // (Serialization) String json = gson.toJson(ints); // ==> json is [1,2,3,4,5] // (Deserialization) Type collectionType = new TypeToken<Collection<Integer>>(){}.getType(); Collection<Integer> ints2 = gson.fromJson(json, collectionType);
자, 객체는 { } 로 묶이고, 필드명:value 형식으로 매핑되어 표현되고, 배열은 [ ] 로 묶여있단 것만 잘 알면된다.
이제 공부한 걸 가지고 이것저것 섞어서 한번 써보자. 2개의 클래스를 만들 것이다.
Member 클래스 – 회원정보를 가지고 있으며, 회원이름과 나이, 그리고 다녔던 학교들의 정보를 list 로 가지고 있다. 학교정보 list 안에 각각의 element는 School 클래스로 정의 되있다.
School 클래스 – 회원이 다녔던 학교정보를 가지고 있다. 학교이름, 학교위치, 입학년도 간단히 3가지 정보.
Member.java
import java.util.List; public class Member { private String name; private int age; private List<School> schools; public Member(String name, int age, List<School> schools){ this.name = name; this.age = age; this.schools = schools; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public List<School> getSchools() { return schools; } public void setSchools(List<School> schools) { this.schools = schools; } }
School.java
public class School { private String name; private String location; private int enterYear; public School(String name, String location, int enterYear){ this.name = name; this.location = location; this.enterYear = enterYear; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public int getEnterYear() { return enterYear; } public void setEnterYear(int enterYear) { this.enterYear = enterYear; } }
자 이런 2개의 클래스가 있다고 하자. Gson 객체를 이용하여 JSON 표현식으로 변환했다가 다시 자바 객체로 되돌리는 작업을 수행해보자.
import java.util.ArrayList; import java.util.List; import com.google.gson.Gson; public class ZExecute { public static void main(String[] args){ Gson gson = new Gson(); List<School> schools = new ArrayList<School>(); schools.add(new School("A학교", "서울", 2000)); schools.add(new School("B학교", "대구", 2003)); schools.add(new School("C학교", "광주", 2006)); String result = gson.toJson(new Member("lee", 20, schools)); System.out.println("=========== JSON 표현식으로 변환 ==========="); System.out.println(result); Member mee = gson.fromJson(result, Member.class); System.out.println(""); System.out.println("=========== 자바 객체로 복원 ==========="); System.out.println(mee.getName()); System.out.println(mee.getAge()); for (School school : mee.getSchools()){ System.out.println(school.getEnterYear()+", " +school.getName()+", " +school.getLocation()); } } }
실행하면 아래의 결과로 출력된다. 잘 변환되고 복원되었음을 알 수 있다.
=========== JSON 표현식으로 변환 ===========
{“name”:”lee”,”age”:20,”schools”:[{“name”:”A학교”,”location”:”서울”,”enterYear”:2000},{“name”:”B학교”,”location”:”대구”,”enterYear”:2003},{“name”:”C학교”,”location”:”광주”,”enterYear”:2006}]}
=========== 자바 객체로 복원 ===========
lee
20
2000, A학교, 서울
2003, B학교, 대구
2006, C학교, 광주