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.