简体   繁体   中英

Error in parsing json with class Kotlin Android

hi i am trying to parse JSON with kotlin

below is my json code

    [{
    "module":"1",
    "books":[{"name":"bookname1","authors":"author1, author 2"},
             {"name":"bookname2","authors":"author1, author 2"},
             {"name":"bookname3","authors":"author1, author 2"}]
},
{
    "module":"2",
    "books":[{"name":"bookname1","authors":"author1, author 2"},
             {"name":"bookname2","authors":"author1, author 2"},
             {"name":"bookname3","authors":"author1, author 2"}]
},
{
    "module":"3",
    "books":[{"name":"bookname1","authors":"author1, author 2"},
             {"name":"bookname2","authors":"author1, author 2"},
             {"name":"bookname3","authors":"author1, author 2"}]
},
{
    "module":"4",
    "books":[{"name":"bookname1","authors":"author1, author 2"},
             {"name":"bookname2","authors":"author1, author 2"},
             {"name":"bookname3","authors":"author1, author 2"}]
},
{
    "module":"5",
    "books":[{"name":"bookname1","authors":"author1, author 2"},
             {"name":"bookname2","authors":"author1, author 2"},
             {"name":"bookname3","authors":"author1, author 2"}]
}]

please note that this json response starts with array

here is my class to parse it

class SemdetailsPArser {

    @SerializedName("module")
    @Expose
    var module: String? = null
    @SerializedName("books")
    @Expose
    var books: List<Book>? = null




}

class Book {

    @SerializedName("name")
    @Expose
    var name: String? = null
    @SerializedName("authors")
    @Expose
    var authors: String? = null

}

And here is my code

//interface

interface SemdetailsFetcher {
    @GET("test/json/sub1.json")
    fun getCurrentSemData(): Call<SemdetailsPArser>
}

here is my code in activity

fun getCurrentData() {
        val retrofit = Retrofit.Builder()
            .baseUrl(BaseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        val service = retrofit.create(SemdetailsFetcher::class.java)
        val call = service.getCurrentSemData()
        call.enqueue(object : Callback, retrofit2.Callback<SemdetailsPArser> {
            override fun onResponse(
                call: retrofit2.Call<SemdetailsPArser>?,
                response: retrofit2.Response<SemdetailsPArser>?
            ) {
               // val thisthig = response?.body();
                println("here 1 ${response?.body().toString()}")
            }

            override fun onFailure(call: Call?, e: IOException?) {
                println("here 2")
            }

            override fun onFailure(call: retrofit2.Call<SemdetailsPArser>?, t: Throwable?) {
                println("here 3 $t")
            }

            override fun onResponse(call: Call, response: Response) {
                if (response.code() == 200) {

                    println("secodn success")
                    val sampleResp = response.body()!!

                    println(sampleResp)
                }
            }


        })
    }

and i am getting this error

here 3 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

I understood that this might be related to my parsing class

here i am getting an array of json info, i tried the same code with another json

{
    "person": {
        "name": "Don",
        "age": 35
    },
    "books": [{
            "id": 800,
            "name": "book 1",
            "description": "clear sky",
            "icon": "01n"
        },
        {
            "id": 801,
            "name": "book 2",
            "description": "clear sky 1",
            "icon": "01N"
        }
    ],

    "city": "bgvnslsl",
    "id": 1851632,
    "bname": "abcd",
    "code": 200
}

this was working perfectly when i changed the parsing class and interface

My problem is that i dont know how to write a class to parse a json response starting with an array

You are expecting list of SemdetailsPArser , so you should define return type as List of SemdetailsPArser

This should fix problem.

interface SemdetailsFetcher {
    @GET("test/json/sub1.json")
    fun getCurrentSemData(): Call<List<SemdetailsPArser>>
}

You also need to change it in other parts of code.

The error you are getting means that you're trying to parse JSON array, thinking it should be JSON object. JSON array is the thing between these [] , while JSON object is in curly brackets like these {} . So your first JSON corresponds to something like List<Module> , it's not an object, but a list of them. Each module has a list of books in it.

So all said, it should be like this

interface SemdetailsFetcher {
    @GET("test/json/sub1.json")
    fun getCurrentSemData(): Call<List<SemdetailsPArser>>
}

By the way, if you define your POJOs right, you won't need all the annotations.

Create SemdetailsPArser class

data class SemdetailsPArser( val books: List<Book>, val module: String )

Next create Book class

data class Book(
val authors: String,
val name: String

)

next in the interface (SemdetailsFetcher)

interface SemdetailsFetcher {
@GET("test/json/sub1.json")
fun getCurrentSemData(): Call<List<SemdetailsPArser>>

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM