반응형

json은 유니티 게임 개발 때나 HTML5 javascript 때 접해봤고 사용도 해봤다. 당시에는 '그런 게 있다더라~'정도로 정말 얕게 알고 사용했다. 잘 알지도 못하는 상태로 사용하려니까 정말 죽을 맛이었다. jsonArray랑 jsonObject가 어떻게 다른 건지 몰라서 회사에서 퇴근도 못하고 25시간 근무를 했을 정도로 말이다. 차라리 특정 언어나 엔진에서만 사용되는 기술이고 메이저 하거나 다른 것에서는 사용할 일이 없는 거면 '그땐 그랬지~'하고 넘기기라도 했을 텐데 json은 정말 많은 곳에서 사용되고 있는 녀석이다. 지금도 안드로이드 개발을 하면서 사용했고, 앞으로 개발일을 하면서 무조건 접할 것이다. 그래서 정확하게 이해하고 싶고 그래야 할 것이다.

이번에 알아보는 것으로 끝을 낼 수는 없을 것이다. 남들이 생각하기에는 단순한 것일지 몰라도 결국 사용하는 건 '나'이기 때문에 이해할 수 있을 때 까지 알아보고 정리해나가려고 한다.

단, 개인적으로 이해하기 위한 단순화가 많이 들어갈 것이고 전문적인 정리가 아니기에 틀릴 수도 있다. 때문에 개념 자체는 알겠는데 정확하게 뭔지는 모르겠고, 대충 알긴 아는데 이해는 안 된다 싶은 사람들에게는 도움이 될 수 있겠지만 완전 처음 접하는 사람에게는 오히려 독이 될 수도 있으니 참고 바란다.


JSON? 이게 뭔데

사전적 정의나 더 구체적으로 따지면 차이가 나겠지만 1차원급으로 단순하게 말하자면 JSON(제이슨)은 '키-값'으로 이루어진 데이터를 텍스트로 변환시켜놓은 데이터라고 할 수 있을 것 같다. 보통은(적어도 내가 지금까지 접해보기로는) 데이터 간의 네트워크 통신에 사용된다.

 

그냥 데이터 그대로 주고받으면 되는 거 아닌가?
 

 

단순히 개념에 대해서 처음 알아봤을 때 했던 생각이다. 뭐 어떻게 보면 맞는 말인데 당연히 이게 되면 이런 게 안 나왔겠지. 어떤 언어이던 개발 공부 기초 단계일 때 '변수'라던가 '데이터 타입'을 접하게 된다. String, Int, Char, Boolean 같은 것들 말이다. 만약 이런 것들만 사용된다면 또 모르겠지만, 데이터 타입은 무수히 많고 표현되는 방식도 다르다. 심지어 데이터 타입에는 클래스나 정의된 것들도 가능하다. 때문에 이런 중구난방 타입들을 가지고 통신을 해야 하니 아예 데이터 타입을 통일시켜버렸다고 하면 될 것 같다. 그래서 위에서 말했듯 JSON은 어떤 데이터든지 텍스트로 변환시킨 거라고 생각하면 편하다. 거기에 사람이 봐도 알아보기 쉽고 단순한 형태를 띄고 있다.

 

 

그래서 JSON이라는 게 어떻게 생긴 건데?

[{"age":27,"name":"John"},{"age":21,"name":"Ava"},{"age":38,"name":"Emma"}]

이런 식으로 생겼다. 여기서 []로 묶여 있는 건 JsonArray이고 {}는 JsonObject이다. 이게 내가 제일 고생했던 부분이기도 하다. 위처럼 생긴 데이터는 비교적 단순한 형태여서 괜찮지만 배열 안에 배열을 넣을 수 있듯 JsonArray를 담고 있는 JsonObject가 또 다른 JsonArray의 데이터가 될 수도 있다. 그래서 복잡한 데이터들은 정말 눈 돌아갈 뻔했다.

여기서 age는 Int 타입이고 name은 String 타입이다. 그리고 age와 name 데이터를 갖고 있는 {}는 배열의 데이터이며 []는 배열 그 자체이다. 이 밖에도 Boolean, Char, Double, Float 등 다른 데이터 타입도 이와 같은 형태로 보인다.

 

 

그래서 어디에 쓰이는 거지?

만약 회원 정보를 받아오는 통신이 있고 결과 값으로 오는 데이터가 위에서 사용했던 데이터라고 생각해보자. 위 데이터를 해석하면 이런 식이다.

이름이 John이라는 사람이 있고 이 사람의 나이는 27살이다.
이름이 Ava이라는 사람이 있고 이 사람의 나이는 21살이다.
이름이 Emma이라는 사람이 있고 이 사람의 나이는 38살이다.

데이터가 총 3개 이므로 회원은 총 3명이다.

물론 서버 단에서 쿼리문으로 조건이 걸려있을 수도 있고, 클라이언트 단에서 조건이 달려있었을 수 있으나 복잡한 경우는 제외하고 생각했을 때는 이러하다.

만약 이걸 '회원정보'라는 클래스로 받아서 사용하고 싶다면? 개인적으로 드는 방법은 따옴표나 콜론, 컴마, 중괄호, 대괄호 등을 조건으로 String 타입이니 Split으로 나누면 되지 않을까 싶다. 하지만 애초부터 배열로 되어 있던 데이터인데 이런 복잡한 방법으로 데이터를 가공하는 건 효율적으로도 안 좋고 매우 복잡하다. 거기에 데이터가 복잡한 형태이면 조건문에 반복문까지 짜려면 정말 힘들다. 또한 가공 과정에서 데이터를 잘못 나눌 수도 있으니 위험성도 존재한다.

 

 

그러면 어떻게 쓰는 거지?

그래서 데이터를 JSON 데이터로 가공할 수 있듯이 JSON 데이터를 데이터로 가공하는 것도 가능하다.(이를 데이터 직렬화(serialization), 역직렬화(deserialization)라고 한다.) 안드로이드에서는 이걸 위해 'GSON'이라는 라이브러리를 사용한다.

implementation 'com.google.code.gson:gson:2.8.9'

먼저 모듈 단위의 build.gradle에 의존성을 추가시켜준다.

 

 

data class sampleData(
    val name: String,
    val age: Int,
)

그리고 받아온 Json 데이터를 클래스로 받아 사용하고 싶으니 데이터 클래스도 생성시켜준다. 꼭 데이터 클래스로 받아 사용할 필요는 없지만 어차피 같은 형태로 만들어진 데이터를 배열로 받아서 사용하는 건데 굳이 사용할 때마다 힘드니까.(그리고 서버와 클라이언트 간에 어떤 데이터로 오고 갈지에 대한 것도 개발자들끼리 API문서를 통해 정하기 때문에 이게 편하다.)

 

 

val datas = "[{\"age\":27,\"name\":\"John\"},{\"age\":21,\"name\":\"Ava\"},{\"age\":38,\"name\":\"Emma\"}]"

private fun convert() {
    val gson = GsonBuilder().create()

    val result = gson.fromJson(datas, Array<sampleData>::class.java)
    for (data in result)
        Log.d(TAG, "data: $data")
}


로그 출력
// data: sampleData(name=John, age=27)
// data: sampleData(name=Ava, age=21)
// data: sampleData(name=Emma, age=38)

그리고 받아온 Json 데이터를 어떤 형태로 받아올지 정하기만 하면 끝이다.

 

 

sampleData라는 데이터 클래스 타입으로 받았으니 당연히 위와 같은 형태로도 사용 가능하다.


package com.solution.myapplication

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.google.gson.GsonBuilder

class MainActivity : AppCompatActivity() {
    val TAG = "SOL_LOG"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        convert()
    }

    val datas = "[{\"age\":27,\"name\":\"John\"},{\"age\":21,\"name\":\"Ava\"},{\"age\":38,\"name\":\"Emma\"}]"
    private fun convert() {
        val gson = GsonBuilder().create()

        val result = gson.fromJson(datas, Array<sampleData>::class.java)
        for (data in result)
            Log.d(TAG, "data: $data.")
    }
}

data class sampleData(
    val name: String,
    val age: Int,
)

서버 통신이 필요한 프로젝트의 경우 JSON은 필수라고 할 수 있다. 데이터를 가공하는 방법, 데이터를 주고받는 방법, 데이터를 사용하는 방법은 어떤 언어를 사용하던 알고 있으면 도움이 되고 사용하기 때문에 제대로 알고 있으면 정말 든든한 지식이라고 생각한다.

아직 나도 사용 경험도 적고 지식도 부족하기 때문에 서버 통신 작업을 접하면서 계속 알아갈 예정이다.

 

 

https://ko.wikipedia.org/wiki/JSON

 

JSON - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. JSON(제이슨[1], JavaScript Object Notation)은 속성-값 쌍(attribute–value pairs), 배열 자료형(array data types) 또는 기타 모든 시리얼화 가능한 값(serializable value) 또는 "키-값

ko.wikipedia.org

https://velog.io/@dev_2dong/JSONObject%EC%99%80-JSONArray%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%99%80-%EC%A0%84%EB%B0%98%EC%A0%81%EC%9D%B8-JSON%ED%98%95%EC%8B%9D%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%EC%95%BC%EA%B8%B0

 

JSONObject와 JSONArray의 차이와 전반적인 JSON형식에 대한 이야기

JSON의 형식 및 JSONObject, JSONArray의 차이에 대해 언급했습니다.

velog.io

 

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기