이전 게시글이 JSON 데이터를 GSON으로 표현하다 찾은 문제점에 대한 글이었는데요. JSON 라이브러리를 통해 사용하는 JSON과 GSON 라이브러리를 통해 사용하는 Json은 미묘한 차이가 있다는 사실을 알게 되었습니다.
이 글을 들어가기 전에 주의해야 할 점이 있다면, JSON의 정의가 제대로 되지 않으면 GSON과 JSON이 다르다고 생각하게 된다는 것입니다. 아래 목차를 따라 정리해보았습니다.
- what is JSON?
- JSON-simple 라이브러리
- what is GSON?
- 결론
What is JSON?
JSON은 어떤 글을 봐도 일단 "가벼운 데이터 교환 형식"이라고 정의되어 있습니다. 일단 JSON을 사용하는 목적이 조금 더 네트워크에게 무리를 주지 않는 선에서 데이터를 교환하고 싶으니 각 프로그램들끼리의 약속에 가까운 것이라고 생각할 수 있습니다.
기본적으로 프로그래밍을 하다 보면 제가 만든 프로그램에서 어떤 또 다른 프로그램(서버)등으로 데이터를 전송해줘야 하는 경우가 있습니다. 이때, 같은 언어로 이루어져 있고 통신을 원하는 프로그램의 제작자와 직접 이야기해서 형식을 정할 수 있다면 아마 데이터를 전송하는데 큰 무리가 없을 겁니다. 어떤 형식으로 데이터를 전달할지에 대해서 직접 얘기해서 정하면 되는 부분이니까요. 하지만 항상 그런 상황이 아닌 상황을 가정해야 하죠. 그 상황은 누군가에게 데이터를 보내야 하는데, 어떤 방식으로 데이터를 보내야하는지 알 수 없는 경우겠죠.
예전에는 XML이 널리 데이터를 전송할 때 이용되는 양식이었습니다. 물론 아직까지도 널리 사용되고 있기도 하지만 XML에 비해 가볍다고 하는 특징은 모바일 어플리케이션 중심인 요즘에는 굉장히 플러스 요소로 자리하고 있죠. 그 덕분인지 JSON에게 자리를 꽤 많이 넘겨준 상태죠. 물론 아직도 형식을 엄격하게 갖춰야 하는 여러가지 언어나 데스크탑 프로그램에서는 XML이 많이 쓰이고 있습니다. (무심코 JSON에 대해 검색해보고 있자면 왠지 현재 데이터 통신은 거의 JSON으로 이루어져 있지 않나 하는 착각이 들기도 합니다.)
{
"name":"Douglas Crockford",
"age": 66,
"from" : "USA",
"education" : ["San Francisco State University", "Newport Harbor High School"]
}
JSON은 위와 같은 예제를 통해 간단하게 확인할 수 있습니다. 물론 더 어렵게도 작성할 수 있지만, 나중에 후술할 GSON이나 JSON 라이브러리를 통해 사용하게 된다면 더 간단하게 이용할 수 있기 때문에 구조 파악을 위한 용도로 보는 것이 좋습니다.
위의 양식을 한 번 살펴보겠습니다. 먼저 {}를 통해 json 오브젝트임을 판별할 수 있습니다. 그 속에 "name" : "Douglas Crockford"중 왼쪽은 key 값, 오른쪽은 value라고 하는 자신이 저장하고자 하는 데이터입니다. value 값에는 기본적으로 Char, Boolean, Int, Double, String, JsonArray, JsonObject등이 올 수 있습니다. key 값은 항상 ""에 쌓여져 있는 String 값이라고 생각하면 됩니다. 단 JsonArray에는 key값이 따로 존재하지 않을 수 있습니다. 이 경우 key 값 대신 index를 이용해 데이터를 추출합니다.
JSON-simple 라이브러리
위에서 살펴보았던 JSON은 저 양식대로 적기만 한다면 데이터를 String 형태로 던져도 아무 문제가 없습니다. 그러나 사람이 직접 JSON data를 관리하려면 쉽지 않습니다. 코딩할 때 ()의 개수를 자주 실수하는 저도 IDE의 도움을 받아 해결하는데, 저같은 사람이 {}를 아무런 도움 없이 제대로 관리하는 것은 신경을 쓴다고 해도 매우 어려운 일입니다.
그런 JSON 데이터를 관리하기 쉽게 도와주는 여러가지 라이브러리가 있습니다. 그 중 코틀린과 자바(둘은 동일한 라이브러리를 사용하기 때문에!)에서 사용되는 기본적인 라이브러리인 JSON-simple을 기준으로 이야기해보겠습니다.
JSON-simple 라이브러리를 사용하게 되면 아래와 같은 클래스들을 이용할 수 있습니다.
- JSONObject: JSON의 오브젝트 객체를 생성. JSON형식에 맞춘 String을 파라미터로 한 생성자가 존재
- JSONArray: JSON의 어레이 객체를 생성. JSON형식에 맞춘 String을 파라미터로 한 생성자가 존재
- JSONParser: String 및 Reader를 통해 JSON을 생성할 수 있음.
- JSONValue: JSON의 value 값을 적절하게 이용하기 위함이지만 기본적으로는 잘 쓰이지 않음
- JSONException: JSON 관련 Exception 처리를 위한 용도
이러한 클래스들을 통해 변수를 만들어내면 아래와 같이 생성과 동시에 데이터를 삽입할 수 있고 생성자를 통해 초기 데이터 값을 집어넣을 수도 있습니다.
val jsonData = JSONObject("{"String":"value"}").put("index", "one")
val arrData = JSONArray("["arrayConstructor"]").add("arrayOne")
jsonData.getString("String")
jsonData.get("String")
jsonData.optString("data", "no data")
arrData.getString(0)
arrData.optString(2,"no data")
또한 아래에서 처럼 getString, get optString을 통해 object 데이터를 불러올 수도 있습니다. 각각 getString은 return type이 String인, get은 return type이 Object인, optString의 경우 return type은 String이지만 혹시 없는 키 값일 경우 두 번째 파라미터 값을 반환해준다는 의미를 지니고 있습니다.
JSONArray의 경우 array 답게 index를 통해 데이터를 가져올 수 있습니다. 0번째 데이터는 arrayConstructor가 될 것이며 optString의 경우 2번째는 없으므로 no data가 동작할 것입니다.
위에서 설명한 입력과 출력, 두가지만 알아도 JSON 데이터를 사용하는 것에는 이제 무리가 없습니다. 여기서 자세하게 JSON에 대해 더 설명해드릴 수도 있겠으나, 이 글의 목적은 어디까지나 제가 JSON vs GSON이라는 검색을 하게 된 제 멍청함을 보완하기 위해 작성하는 글이기 때문에 다음으로 넘어가도록 하겠습니다. 시간이 된다면 JSON에 대해 다음에 좀 더 다뤄보도록 하겠습니다.
What is GSON?
그렇다면 GSON이란 무엇일까요. GSON은 JSON 데이터를 이용하기 위해 만들어진 라이브러리 중 하나입니다. google에서 제작했죠. GSON을 나타내는 가장 큰 특징은 JAVA나 Kotlin 객체를 JSON 데이터로 손쉽게 변환할 수도, 그 반대도 가능하게 해준다는 점입니다.
@Serializable
data class Student(var name: String, var age: Int, var gender: String, var major: String)
fun main(){
val data = Student("doh", 18, "girl", "computer")
val stringData = Json.encodeToString(data)
val result = Json.decodeFromString<Student>(stringData)
val dataFromJson = Gson().fromJson(result, Student::class.java)
}
이러한 데이터 클래스를 가지고 있을 때 위와 같은 형식의 코드를 이용하면 쉽게 데이터 클래스를 JSON 타입으로 변환시켜줄 수 있습니다. 물론 JSON data를 data class로 변환하는 코드도 있습니다. fromJson을 이용하면 쉽게 변환할 수 있습니다.
물론 GSON 역시 JsonObject나 JsonArray를 쉽게 만들 수 있습니다. 그러나 이 친구는 JSON-simple과는 다르게 클래스가 JsonObject로 대소문자가 다르게 나열되어 있습니다. 사실 큰 차이는 아니기 때문에(실제로 GSON을 사용하는 이유는 겨우 대소문자가 다르다는 것 따위로는 명명될 수 없기 때문에) 신경쓰지는 않으셔도 됩니다. 그러나 이 두개가 분명 다른 객체라는 것은 인지하셔야 합니다.(제가 그걸 못해서 코드를 펑펑 터뜨렸기 때문이죠.)
위에서 설명했든 simple의 경우에는 getString, getInt, optInt 등을 이용해서 데이터를 받아왔습니다. 거기다 get으로 불러오게 되면 object 타입으로 불러와서 형태만 맞다면 어떤 것으로든 변화시킬 수 있죠. 그러나 GSON은 기본적으로 get을 통해 데이터를 불러오게 되면 JsonElement라는 데이터 형태로 가지고 옵니다. 물론 GSON도 getAsString()이나 getAsInt()와 같은 메소드들이 있어 getString, getInt와 동일한 작용을 할 수 있도록 도와줍니다. 하지만 세부적인 내용에서 분명 차이가 존재하죠.
이러한 상황은 항상 동일한 형태의 Json을 들고오게 되는 경우에는 문제가 없을 수도 있습니다만, 만일 어떤 data class의 Json이 들어올 지 모른다면, 그것을 가공해야 한다면 결국 data class 별로 직접 get type을 정의해주거나, 아니면 일관되게 들고올 수 있어야 합니다. 그래서 JsonElement의 특성을 이해해야 효율적인 코드를 작성할 수 있게 되는 것입니다.
결론
사실 이 게시글을 적는 이유는 결국 여기에 있습니다. 학생때부터 JSON-simple 라이브러리와 JSON-lib만 써오던 저로서는 당연히 저 라이브러리에 든 형태가 기본 양식이며 다른 라이브러리들이 이 라이브러리를 가지고 변형한 것이라 생각했죠. 물론 이건 제가 이 글을 쓰면서도 알게 되었지만 조금만 검색을 해보면 다 알 수 있는 내용입니다.
Json이란 위에서 서술한 데이터의 형태에 불과하며, 그것을 사용하는 것은 어떠한 라이브러리를 쓰는지에 달려있다는 것입니다. 거기에 GSON이라는 라이브러리는 Json 데이터를 자바나 코틀린의 객체에 좀 더 쉽게 접근하고 사용할 수 있게 가공했다는 점입니다. 더욱이 기본적인 Json 가공은 물론이구요.
이러한 라이브러리들은 기본적으로 Json 데이터를 다루는 점에서는 동일하지만, 그 데이터를 참조하고 생성하는 과정과 저장하는 과정들이 조금씩 다르다는 것입니다. 그 점을 꼭 유의하면서 자신이 사용해야 하는 데이터에 맞게 Json 라이브러리를 선택했으면 좋겠습니다.
'기타' 카테고리의 다른 글
가볍게 보는 아키텍처 vs 디자인 패턴 (0) | 2024.07.11 |
---|---|
프로퍼티, 그리고 위임 (0) | 2022.10.26 |
함수와 메소드(멤버 함수) (0) | 2022.05.04 |
클라우드 컴퓨팅 서비스란? (0) | 2022.04.13 |
해시 함수?(feat.computer science) (0) | 2021.06.17 |
댓글