0

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

2
  • 1
    your parsing will not work as your response is json array and the code you have written expects a json object response Commented Nov 1, 2019 at 11:43
  • yes exactly, i understood that, can you shed some light on how to achieve that?i tried the online gson generator, the above class is generated with that same json input Commented Nov 1, 2019 at 11:45

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

1 Comment

thank you, the way i called the class was wrong, so careless of me, cost me a day
0

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>>

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.