I'm really new in programming, and recently started a project in Kotlin with Android Studio.
So, I have a problem with a JSON object. I get data from an BroadcastReceiver object, a String to be more specific, with the next format:
{"s1":1}
This, is a simple string. So I took in a function call toJson and I do this.
private fun toJson(data:String): JSONObject {
var newData: String = data.replace("\"","")
newData = newData.replace("{","")
newData = newData.replace("}","")
val newObject = newData.split(":")
val name = newObject[0]
val value = newObject[1]
val rootObject = JSONObject()
rootObject.put(name,value)
return rootObject
}
Im doing this the right way?, how can I improve my code?
Thanks for your help, and sorry for my english!
Welcome to StackOverflow!
In 2019 no-one is really parsing JSON manually. It's much easier to use Gson library. It takes as an input your object and spits out JSON string and vice-versa.
Example:
data class MyClass(#SerializedName("s1") val s1: Int)
val myClass: MyClass = Gson().fromJson(data, MyClass::class.java)
val outputJson: String = Gson().toJson(myClass)
This way you're not working with JSON string directly but rather with Kotlin object which is type-safe and more convenient.
Look at the docs. It's pretty big and easy to understand
Here is some tutorials:
https://www.youtube.com/watch?v=f-kcvxYZrB4
http://www.studytrails.com/java/json/java-google-json-introduction/
https://www.tutorialspoint.com/gson/index.htm
UPDATE: If you really want to use JSONObject then use its constructor with a string parameter which parses your JSON string automatically.
val jsonObject = JSONObject(data)
Best way is using kotlinx.serialization. turn a Kotlin object into its JSON representation and back marking its class with the #Serializable annotation, and using the provided encodeToString and decodeFromString<T> extension functions on the Json object:
import kotlinx.serialization.*
import kotlinx.serialization.json.*
#Serializable
data class User(val name: String, val yearOfBirth: Int)
// Serialization (Kotlin object to JSON string)
val data = User("Louis", 1901)
val string = Json.encodeToString(data)
println(string) // {"name":"Louis","yearOfBirth":1901}
// Deserialization (JSON string to Kotlin object)
val obj = Json.decodeFromString<User>(string)
println(obj) // User(name=Louis, yearOfBirth=1901)
Further examples: https://blog.jetbrains.com/kotlin/2020/10/kotlinx-serialization-1-0-released/
I am adding 3 templates here for Kotlin Developers, It will solve json converting & parsing problems.
//Json Array template
{
"json_id": "12.4",
"json_name": "name of the array",
"json_image": "https://image_path",
"json_description": "Description of the Json Array"
}
Kotlin Model class
data class JsonDataParser(
#SerializedName("json_id") val id: Long,
#SerializedName("json_name") val name: String,
#SerializedName("json_image") val image: String,
#SerializedName("json_description") val description: String
)
Converting to Json String from the Model Class
val gson = Gson()
val json = gson.toJson(jsonDataParser)
Parsing from Json file/Strong
val json = getJson()
val topic = gson.fromJson(json, JsonDataParser::class.java)
Related
I have an JSONObject which is creating in the following way.
For a special reason, I have to convert it to Gson in this way, as i can modify only extractDataToString() method. But I do not get proper value after conversion.
fun createJsonString() {
val headerJson = JSONObject()
headerJson.put("typ1", "value1")
headerJson.put("typ2", "value2")
extractData(headerJson.toString())
}
fun extractDataToString(jsonString: String) {
val headerJson = Gson().fromJson(jsonString, JsonObject::class.java)
val resultType1 = headerJson.remove("typ1")?.toString() // Here, resultType1 becomes
"value1", but it should be
value1 that is extra qutomation
mark is being added.
}
Why extra quotation mark is being added? Can anyone please help? I am a newbie.
Call
.getAsString()
Instead of
toString()
at the end
ref : docs
I wonder what is the way to convert a Kotlin data class into its equivalent json string. Json keys should be configurable.
Let's say I have a class,
data class Student(name: String?, roll: Int?, mark: Int?) {
}
I want to make a Json from this Student object where keys will be,
stundent_name, stundent_roll, stundent_mark
Moreover, I may also need to make a json from list of student with key students. How can I do so? I know using Gson I can create object from json string. How to do the reverse?
data class Student(
#SerializedName("stundent_name")
val name: String?,
#SerializedName("stundent_roll")
val roll: Int?,
#SerializedName("stundent_mark")
val mark: Int?
)
And the code for convertion is:
val gson = Gson()
val student = Student("John", 1, 5)
gson.toJson(student)
This code makes String like this:
{"stundent_mark":5,"stundent_name":"John","stundent_roll":1}
And if you need to create JsonArray, just do the same with your List of students:
gson.toJson(list)
this is my data class, need to parse the arraylist of type link
class DetailResponse {
data class BasicInfo (
#SerializedName("favorite") val isFavorite: Boolean,
#SerializedName("screenshots") val screenshots: ArrayList<Link>
)
data class Link (
#SerializedName("href") val href: String
)
}
What you have done is correct. Now you just have to use Gson to convert this JSON to object
val gson = Gson()
val detailResponse = gson.fromJson(resp,DetailedResponse::class.java)
where "resp" is your json string.
I use this class to store data
public class Item(var name:String,
var description:String?=null){
}
And use it in ArrayList
public var itemList = ArrayList<Item>()
Use this code to serialize the object
val gs=Gson()
val itemListJsonString = gs.toJson(itemList)
And deserialize
itemList = gs.fromJson<ArrayList<Item>>(itemListJsonString, ArrayList::class.java)
But this method will give me LinkedTreeMap, not Item, I cannot cast LinkedTreeMap to Item
What is correct way to deserialize to json in Kotlin?
Try this code for deserialize list
val gson = Gson()
val itemType = object : TypeToken<List<Item>>() {}.type
itemList = gson.fromJson<List<Item>>(itemListJsonString, itemType)
You can define a inline reified extension function like:
internal inline fun <reified T> Gson.fromJson(json: String) =
fromJson<T>(json, object : TypeToken<T>() {}.type)
And use it like:
val itemList: List<Item> = gson.fromJson(itemListJsonString)
By default, types are erased at runtime, so Gson cannot know which kind of List it has to deserialize. However, when you declare the type as reified you preserve it at runtime. So now Gson has enough information to deserialize the List (or any other generic Object).
In my code I just use:
import com.google.gson.Gson
Gson().fromJson(string_var, Array<Item>::class.java).toList() as ArrayList<Type>
I give here a complete example.
First the type and the list array:
class Item(var name:String,
var description:String?=null)
var itemList = ArrayList<Item>()
The main code:
itemList.add( Item("Ball","round stuff"))
itemList.add(Item("Box","parallelepiped stuff"))
val striJSON = Gson().toJson(itemList) // To JSON
val backList = Gson().fromJson( // Back to another variable
striJSON, Array<Item>::class.java).toList() as ArrayList<Item>
val striJSONBack = Gson().toJson(backList) // To JSON again
if (striJSON==striJSONBack) println("***ok***")
The exit:
***OK***
Instead of the accepted answer (that works but creates an object to get its type), you could just do:
val gson = Gson()
itemList = gson.fromJson(itemListJsonString, Array<Item>::class.java)
There "Array" represents a Java array when targeting the JVM platform. That's not an ArrayList but you can access the items (that's usually all is needed after parsing JSON).
If you still need to manipulate the list you could easily convert it to mutable by doing:
itemsList.toMutableList()
I've been trying to parse JSON from an url for hours now but I'm too stupid I guess
I have tried
val result = URL("http://date.jsontest.com/").readText()
but it crashes
java.net.MalformedURLException: no protocol: date.jsontest.com
I have tried Klaxon's library
fun parse(name: String) : Any? {
val cls = Parser::class.java
return cls.getResourceAsStream(name)?.let {
inputStream -> return Parser().parse(inputStream)
}
}
val obj = parse("http://date.jsontest.com/") as JsonObject
but it also crashes
kotlin.TypeCastException: null cannot be cast to non-null type com.beust.klaxon.JsonObject
Can someone please write in Kotlin the simpliest way to parse data from this link http://date.jsontest.com/
Hard to say why you are getting an error. Since this line is correct and working.
val result = URL("http://date.jsontest.com/").readText()
For the parse method. It does not work, becase it expects path to a JSON file but is getting a URL String.
Simplest example using Klaxon would be this.
val result = URL("http://date.jsontest.com/").readText()
val parser: Parser = Parser()
val stringBuilder: StringBuilder = StringBuilder(result)
val json: JsonObject = parser.parse(stringBuilder) as JsonObject
println("Time : ${json.string("time")}, Since epoch : ${json.long("milliseconds_since_epoch")}, Date : ${json.string("date")}, ")