마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

gson 복잡한 json의 경우 파싱

0 추천

gson을 사용해보고싶은데 구글에보면 간단한 json형태만 있어서요.. { } 이렇게 뎁스하나만 있는?

공공 api를 이용해서 해보려는데 이런식으로 data클래스안에 data클래스 넣은 형식으로 쓰고있고 

body.response.body.... 이런식으로 해당 위치까지 타고가다보면 잘됩니다 

구글링해서 

val gson = Gson()
                    val json = gson.toJson(FestivalInformResponse::class.java)
                    val getJson = gson.toJson(json, FestivalInformResponse::class.java)

이런식으로 써봤는데 잘되질 않더라구요.. 저렇게 복잡한 json으로 되있을경우엔 어떻게 써야되는건가요?

data class FestivalInformResponse(
    @SerializedName("response")
    val response: Response
) {
    data class Response(
        @SerializedName("body")
        val body: Body,
        @SerializedName("header")
        val header: Header
    ) {
        data class Body(
            @SerializedName("items")
            val items: Items,
            @SerializedName("numOfRows")
            val numOfRows: Int,
            @SerializedName("pageNo")
            val pageNo: Int,
            @SerializedName("totalCount")
            val totalCount: Int
        ) {

질문수글자제한이있어서 내용은 지우고 뎁스는 이렇습니다

{

    "response": {

        },

        "body": {

            "items": {

                "item": [

                    {

             .....

                    }

              ]

}

수원통학러 (3,570 포인트) 님이 2020년 9월 13일 질문

2개의 답변

0 추천

뎁스별로 모델 클래스를 생성하셔서 파싱하시면 됩니다.

가령

class Result {

    val response : BodyResult = BodyResult()

}

이건 하위가 리스트가 아닌 오브젝트형 클래스를 받을 때, 즉 하위가 { } 요렇게 감싸져 있을때

리스트형태인 [] 요렇게 감싸져 있을때엔

val response : ArrayList<BodyResult> = ArrayList<BodyResult>()

뭐 이런식으로 받고

BodyResult 클래스는

class BodyResult {

     

@SerializedName("total_count")

    val totalCount : Int = -1

    val count : Int = -1

    val items :  : ArrayList<BodyItem> = ArrayList<BodyItem>()

내부에 또 리스트형으로 있으면 요렇게 또 받아줍니다.

}

이해가 가실랑가 모르것네요 ^^ 이해안가면 댓글다세요

쭈쭈총각 (17,750 포인트) 님이 2020년 9월 14일 답변
package com.example.gsontest

import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName

data class FestivalInformResponse(
    @SerializedName("response")
    val response: Response
)
data class Response(
    @SerializedName("body")
    val body: Body,
    @SerializedName("header")
    val header: Header
)
data class Body(
    @SerializedName("items")
    val items: Items,
    @SerializedName("numOfRows")
    val numOfRows: Int,
    @SerializedName("pageNo")
    val pageNo: Int,
    @SerializedName("totalCount")
    val totalCount: Int
)
data class Header(
    @SerializedName("items")
    val items: Items,
    @SerializedName("numOfRows")
    val numOfRows: Int,
    @SerializedName("pageNo")
    val pageNo: Int,
    @SerializedName("totalCount")
    val totalCount: Int
)
data class Items(
    @SerializedName("item")
    val item: List<Item>
)
data class Item(
    @SerializedName("addr1")
    val addr1: String,
    @SerializedName("areacode")
    val areacode: String,
    @SerializedName("cat1")
    val cat1: String,
    @SerializedName("cat2")
    val cat2: String,
    @SerializedName("cat3")
    val cat3: String,
    @SerializedName("contentid")
    val contentid: String,
    @SerializedName("contenttypeid")
    val contenttypeid: String,
    @SerializedName("createdtime")
    @Expose
    val createdtime: String,
    @SerializedName("eventenddate")
    @Expose
    val eventenddate: String,
    @SerializedName("eventstartdate")
    val eventstartdate: String,
    @SerializedName("firstimage")
    val firstimage: String,
    @SerializedName("mapx")
    val mapx: String,
    @SerializedName("mapy")
    val mapy: String,
    @SerializedName("mlevel")
    val mlevel: String,
    @SerializedName("modifiedtime")
    val modifiedtime: String,
    @SerializedName("readcount")
    val readcount: String,
    @SerializedName("sigungucode")
    val sigungucode: String,
    @SerializedName("tel")
    val tel: String,
    @SerializedName("title")
    val title: String
)
해당처럼 클래스를 쪼개고
                    val gson = Gson()
                    val json = gson.toJson(FestivalInformResponse::class.java)
                    val test = gson.fromJson(json, FestivalInformResponse::class.java)
                    Log.e("tag", "getJson " + test)
이렇게써봤는데도 잘안되네요 java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: com.example.gsontest.FestivalInformResponse. Forgot to register a type adapter?
이런에러가 나서 구글링해보면서 해결해보려했는데 막혔습니다.. 방법이없을까요
Retrofit2를 사용하시고, 제안드린 방법대로 파싱해보세요.
저렇게 복잡하고 길게 쓸필요도 없고, response 받는 곳에 최상위 Class 하나만 선언하면 파싱 끝이고 해당 클래스데이터 꺼내 쓰기만 하면 됩니다.
잘이해가안갑니다 현재 레트로핏사용중입니다!
            "items": {

                "item": [

                    {

             .....

                    }

              ]

여기에 item 안에있는애들을 꺼내오고싶은데 어떤걸 선언해야하는지..
현재 응답받을때는 이렇게 되어있습니다
            override fun onResponse(call: Call<FestivalInformResponse>, response: Response<FestivalInformResponse>) {
                if(response.isSuccessful) {

                }
            }
FestivalInformResponse가 최상위 클래스아닌가요 이경우에는? 잘 이해가안됩니다 ㅠㅠ
0 추천
https://github.com/susemi99/JungnangWomen

공공데이터가 사용하기 어렵게 돼있는데, 각각을 클래스로 만들어주면 되더라고요
쎄미 (162,410 포인트) 님이 2020년 9월 15일 답변
깃허브봐도 잘이해가 안됩니다..
            override fun onResponse(call: Call<FestivalInformResponse>, response: Response<FestivalInformResponse>) {
                if(response.isSuccessful) {
                    Log.e("tag", "addr " + response.body()?.response?.body?.items?.item)

                }
            }
data 클래스를 하나하나 파일로 다시쪼개서 넣어주고 해도
item까지가려면 저렇게 log에 쓴듯이 item을 타고타고 들어가야되는데
주신 깃허브에도비슷한것?같더라구요.. 그래서 잘이해가 안갑니다
그렇게 쓰는게 맞습니다. 구조를 더 간단하게 하는 것보다는 data 클래스를 여러 개로 나누는게 더 편합니다.
...