Reputation: 1157
I have the following json generated from a WordPress Post:
{
"events":[
{
"id":4651,
"title":"Test title",
"description":"testttt",
"image": {
url: "https://myhost.tv/wp-content/uploads/2019/07/event2.jpg",
id: "4652"}
}
]
}
My model for json is as follows:
data class EventsFeed(val events: Array<Events>)
data class Events (
val id : Int,
val title : String,
val description : String,
val image : Image
)
data class Image (
val url : String,
val id : Int,
)
I do the parsing with Json and everything works fine, but when I do a POST in wordpress and I don't put an image, the value of the Image
key puts me as afalse
, like this:
{
"events":[
{
"id":4651,
"title":"Stand Up Comedy",
"description":"testttt",
"image":false
}
]
}
And just because image
has the valuefalse
, the parsing returns an error: Expected BEGIN_OBJECT but was BOOLEAN at line 1 column 5781 path $ .events [1] .image
What can I do so that when the post has no image to parse correctly ignoring the value false
or in any case if it isfalse
please keep it a default image (https://myhost.com/image_defaul.jpg
)
The json is generated by the plugin for Wordpress: The Events Calendar: Demo json here
My function (usen Volley and Gson) for parsing is as follows (the data array is sent to an adapter for display in a recyclerview)
fun jsonObjectRequest() {
Log.i(LOG_TAG, "jsonObjectRequest")
// Instantiate the RequestQueue.
val queue = Volley.newRequestQueue(activity)
val url = "https://myhost.tv/wp-json/tribe/events/v1/events"
// Request a JSONObject response from the provided URL.
val jsonObjectRequest = JsonObjectRequest( url, null,
Response.Listener { response ->
Log.i(LOG_TAG, "Response is: $response")
val gson = Gson()
val homeEvents = gson.fromJson(response.toString(), EventsFeed::class.java)
activity?.runOnUiThread {
recyclerEvents.adapter = AdaptadorEventos(homeEvents)
}
},
Response.ErrorListener { error ->
error.printStackTrace()
Log.e(LOG_TAG, "That didn't work!")
}
)
// Add the request to the RequestQueue.
queue.add(jsonObjectRequest)
}
Upvotes: 0
Views: 1200
Reputation: 382
The reason why your post method is not getting the Image Class object is because of the json is not a valid json, You may validate it on https://jsonlint.com/. The reason is: "url"
and "id"
keys are not surrounded by "". Take a look at the below solution, it works perfectly:
package com.example.myapplication
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import com.google.gson.Gson
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getEvemtsObject()
}
private val jsonString = " {\n" +
" \t\"events\": [{\n" +
" \t\t\"id\": 4651,\n" +
" \t\t\"title\": \"Test title\",\n" +
" \t\t\"description\": \"testttt\",\n" +
" \t\t\"image\": {\n" +
" \t\t\t\"url\": \"https://myhost.tv/wp-content/uploads/2019/07/event2.jpg\",\n" +
" \t\t\t\"id\": \"4652\"\n" +
" \t\t}\n" +
" \t}]\n" +
" }"
private fun getEvemtsObject() {
val gson = Gson()
System.out.println("from_gson ---> " + gson.fromJson<EventsFeed>(jsonString,EventsFeed::class.java))
}
}
Upvotes: 2
Reputation: 1376
the image parameter in constructor should be nullable. rewrite your class like this
data class Events (
val id : Int,
val title : String,
val description : String,
var image : Image? = null)
and change your API to send null
instead of false
.
Upvotes: 1
Reputation: 8442
You can use custom Gson deserializer like this:
class EventsDeserializer : JsonDeserializer<Events> {
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Events {
val jsonObject = json.asJsonObject
return Events(
id = jsonObject.get("id").asInt,
title = jsonObject.get("title").asString,
description = jsonObject.get("description").asString,
image = parseImage(context, jsonObject.get("image"))
)
}
private fun parseImage(context: JsonDeserializationContext, json: JsonElement): Image =
try {
context.deserialize(json, Image::class.java)
} catch (_: Throwable) {
Image("https://myhost.com/image_defaul.jpg", 0)
}
}
and here is the test of your json:
fun main() {
val gson = GsonBuilder()
.registerTypeAdapter(Events::class.java, EventsDeserializer())
.create()
val json = """
{
"events": [
{
"id": 4651,
"title": "Stand Up Comedy",
"description": "testttt",
"image": false
}
]
}
""".trimIndent()
val events = gson.fromJson(json, EventsFeed::class.java)
}
Upvotes: 1
Reputation: 76769
This might also be an option (but fixing the API is the better option):
val image: Any
Upvotes: 0