Json response looks like this:
{
"status": 1,
"data": [
[
{
"id": "4iQDR9r1Ch",
"body": "test test",
"da": "1601575850",
"dm": "1601575850"
}
]
]
}
And my classes:
data class NotesListResponse(
#SerializedName("status") val status: Int,
#SerializedName("data") val data: List<List<NoteResponse>>)
data class NoteResponse(
#SerializedName("id") val id: String,
#SerializedName("body") val body: String,
#SerializedName("da") val da: String,
#SerializedName("dm") val dm: String
)
Error message: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 48 path $.data[0][0].body
What's wrong? JSON is valid and classes were checked for correctness
Try the following if you have access to the Gson class. The lenient mode may allow you to see if it works and there are characters that the non-lenient mode can't parse.
Gson gson = new Gson();
JsonReader reader = new JsonReader(new StringReader(<insert response>));
reader.setLenient(true);
Related
I have the following JSON structure that I getting from the server:
{
"a": {
"something": "something",
"something2": {
"test": "12345",
"test2": "1234",
},
"something3": "something3"
},
"b": {
"something": "something",
"something2": {
"test": "12365",
"test2": "12",
},
"something3": "something3"
}
}
I can get more objects than "a" and "b".
I need to create DTO in Kotlin, I tried this DTO:
data class Root(
val root: Map<String, Something>
)
data class Something(
val something: String,
val something3: String,
val something2: Something2
)
data class Something2(
val test: String,
val test2: String
)
I use Retrofit library, it automatically parse JSON data to kotlin data class
I always get null from this DTO, how to write DTO for this JSON structure correctly?
I'm using thingspeak and I have successfully got thingspeak to fetch the json data using okhttp but I don't know how to parse it correctly using klaxon.
Here is the code
private fun funButton1() {
println("Attempting to get JSON data!")
val url = "https://api.thingspeak.com/channels/1029606/feeds.json?results=1"
val request = Request.Builder().url(url).build()
val client = OkHttpClient()
client.newCall(request).enqueue(object: Callback {
override fun onResponse(call: Call, response: Response) {
val body = response.body?.string()
println(body)
class feeds (val field1: String)
val result = Klaxon()
.parse<feeds>(body.toString())
textView.text = result
}
override fun onFailure(call: Call, e: IOException) {
println("Failed to execute request!")
}
})
This is the json data from the thingspeak
{
"channel": {
"id": 1029606,
"name": "LED ",
"description": "Acts as a medium for the phone and arduino \r\nRules : 1 = LED ON 0 = LED OFF ",
"latitude": "0.0",
"longitude": "0.0",
"field1": "LED STATUS",
"created_at": "2020-04-01T17:19:03Z",
"updated_at": "2020-04-01T17:20:39Z",
"last_entry_id": 25
},
"feeds": [
{
"created_at": "2020-05-11T02:58:07Z",
"entry_id": 25,
"field1": "1"
}
]
}
Im trying to get the value of field1 which the value is one but I don't know how I'm supposed to do that because im stupid. But I'm hoping that someone could show me how to use klaxon properly to get the json data.
For Klaxon, you'll need to create a class which represent the structure of your JSON.
f.e. if you get a JSON with:
{
"username": "admin",
"password": "admin"
}
you wanna make a class which looks like that:
class myClass(val username:String, val password:String)
Then, you can parse it like you are doing.
For your JSON, you'll need a bigger Class.
For the Sake of simplicity, I'll just make a class for feeds and a class for the channel:
class Feed(val created_at:String, val entry_id: Int, val field1:String)
class Channel(val id: Int, val name: String, val description: String, val latitude: String, val longitude:String, val field1: String, val created_at: String, val updated_at: String, val last_entry_id: Int)
Then you can use this class to parse your JSON:
class Thingspeak(val channel: Channel, val feeds: ArrayList<Feed>)
Please let me know if it worked for you!
I am a newbie in scala. i try to read a json and parse it using json4s library.
Already written the case class and code for reading and parsing the sample json file.
I need to iterate the json and print the details of each attribute's.
Case Class
case class VehicleDetails(
name: String,
manufacturer: String,
model: String,
year: String,
color: String,
seat: Int,
variants: Seq[String],
engine: Int,
dealer: Map[String, String],
franchise: Map[String, String])
The json data and the code i tried is given below.
import org.json4s._
import org.json4s.jackson.JsonMethods._
import org.json4s.DefaultFormats
object CarDetails extends App {
val json = parse("""{
"vehicle_details": [
{
"CAR": {
"name": "Brezza",
"manufacturer": "Maruti",
"model": "LDI",
"year": 2019,
"color": "Blue",
"seat": 5,
"engine": 1,
"cylinder": 4,
"variants": [
"LDI",
"LDI(O)",
"VDI",
"VDI(O)",
"ZDI",
"ZDI+"
],
"dealer": {
"kerala": "Popular"
},
"franchise": {
"ekm": "popular_ekm"
}
},
"SUV": {
"name": "Scross",
"manufacturer": "Maruti",
"model": "LDI",
"year": 2020,
"color": "Blue",
"variants": [
"LDI",
"VDI",
"ZDI"
],
"dealer": {
"kerala": "Popular"
},
"franchise": {
"ekm": "popular_ekm"
}
}
}
]
}""")
implicit val formats = DefaultFormats
val definition = json.extract[VehicleDetails.Definition]
val elements = (json \\ "vehicle_details").children
This pretty close, just a few small changes needed.
First, create a class that encapsulates all the JSON data:
case class AllDetails(vehicle_details: List[Map[String, VehicleDetails]])
Then just extract that class from the json
implicit val formats = DefaultFormats
val details = Extraction.extract[AllDetails](json)
With this particular JSON the seat and engine fields are not present in all the records so you need to modify VehicleDetails to make these Option values:
case class VehicleDetails(
name: String,
manufacturer: String,
model: String,
year: String,
color: String,
seat: Option[Int],
variants: Seq[String],
engine: Option[Int],
dealer: Map[String, String],
franchise: Map[String, String]
)
[ Other values that might be omitted in other records will also need to be Option values ]
You can unpick the result using standard Scala methods. For example
res.vehicle_details.headOption.foreach { cars =>
val typeNames = cars.keys.mkString(", ")
println(s"Car types: $typeNames")
cars.foreach { case (car, details) =>
println(s"Car type: $car")
println(s"\tName: ${details.name}")
val variants = details.variants.mkString("[", ", ", "]")
println(s"\tVariants: $variants")
}
}
To get back to the raw JSON, use Serialization:
import org.json4s.jackson.Serialization
val newJson = Serialization.write(res)
println(newJson)
At First: I know the JSON should contain a array with key-value-Pairs, but it's not my API so I can't change it.
This is what the response looks like:
{
"translations": {
"my.key.nr.0": "Value 0",
"my.key.nr.1": "Value 1",
"my.key.nr.2": "Value 2",
"my.key.nr.3": "Value 3",
},
"hash": "123xyz",
"length": 3,
"language": "de"
}
And this is my DTO so far:
data class TranslationsDto(
val translations: ??????????, // <-- dont't know what to use here
val hash: String?,
val length: Int?,
val language: String?
)
Finally, here's my Problem:
I need to parse the response (at least Retrofit should parse the response) to a DTO I can use in my App. If the value of translations would be a array there would be no problem but I can't get it how to parse this JSON structure.
Maybe anyone of you have some ideas?
damn... sometimes I'm pretty blind after all...
Just use Map<String,String> :
data class TranslationsDto(
val translations: Map<String,String>?,
val hash: String?,
val length: Int?,
val language: String?
)
I'm using lift-json to deserialize simple objects from a POST request. Example:
{"id": "35", "name": "My topic", "slug": "my-slug", "imageUrl": "http://foo.bar/image.png"}
class definition:
class Topic(var id: Option[Long], var name: String, val slug: String, val imageUrl: String)
Then I use
read[Topic](jsonString)
Is it possible to get json-lift to read the id as a Long automatically?
You can do it by converting the JSON.
val json = parse("""{"id": "35", "name": "My topic", ...}""")
json transform { case JField("id", JString(s)) => JField("id", JInt(s.toInt)) }
And then extract a case class from that transformed JSON.