Reputation: 1105
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
Upvotes: 0
Views: 1365
Reputation: 661
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>>
}
Upvotes: 0
Reputation: 1505
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.
Upvotes: 1
Reputation: 319
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.
Upvotes: 1