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?
)
Related
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);
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 have a class called Post which will have categories property as follows
data class Post (
#SerializedName("id")
val idPost: String?,
val categories: Category?
)
data class Category(
val id: String?,
val label: String?
)
And my JSON
{
"id": 1,
"categories":
{
"id": "123",
"label": "XYZ"
},
...
}
Now I wonder whether can I do it differently. I need only the id from categories.
I tried
data class Post (
#SerializedName("id")
val idPost: String?,
#SerializedName("categories.id")
val categories: String?
)
but it doesn't work.
Can I get the value from a nested object of json without creating an extra class?
I'm having issues creating a struct to parse JSON in Swift 4. I'm able to parse small JSONs and JSONDecoder seems to work fine. Just need help to create a struct to parse JSON like that:
{
"main": {
"solutions": [
{
"exersises": [
{
"book_title": "test",
"release_date": "2015-01-12T11:00",
"price": 100,
"additional": [
{
"item1": "test",
"item2": "test",
"number": 1
},
{
"item1": "test2",
"item2": "test2",
"number": 2
}
],
"availability": "Yes",
"item_id": 43534
}
]
}
]
}
}
What kind of struct do I need to get to value of book_title for example?
Its really easy. Your main probem is most likely root element. Let me get first layer or two for you.
let decoded = try JSONDecoder().decode(MainJSON.self, from: data)
class MainJSON: Codable {
var main:SolutionJSON?
}
class SolutionJSON: Codable {
var exercises:[ExercisesJSON]?
}
class ExercisesJSON: Codable {
var bookTitle: String?
var releaseDate: String?
var price: Double?
... etc
enum CodingKeys: String, CodingKey {
case bookTitle = "book_title"
case releaseDate = "release_date"
case price = "price"
}
}
ExerciseJSON also uses Codable interface which lets remap json properties into swift properties if they don't match. Hope this helps.
i prefer to give a general solution not only for this condition
it is very simple just download and run this MACOS APP from GITHUB
run it in your mac by XCODE and but your JSON in it,
it will make Models for any complex JSON
notes
1 if JSON keys have a capital character in the first it will be small
, so after copying model you need to change it like the JSON
2 if two JSON objects have the same structure and the same key names it will be only one model
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.