Leave a rating/review
Notes: 07. Parse JSON Data
The student materials have been reviewed and are updated as of July 2022.
After practicting parsing the data manually, it’s time to see how you can do it automatically, using a library called GSON.
GSON is a library used to serialize and deserialize objects from JSON to Kotlin or Java objects, and to JSON from Kotlin or Java objects. It can do this even with generics & deep nested object structures. Let’s see how it works!
To begin using GSON, first open up app-module’s build.gradle file. Now add the following dependency:
implementation 'com.google.code.gson:gson:2.8.6'
Sync the project, and you can access the dependency! Now, just like with the previous calls, you need to add the network status checker, and the necessary checks and threading to the NotesFragment. Open up NotesFragment.kt, and add the following code:
private val networkStatusChecker by lazy {
NetworkStatusChecker(activity?.getSystemService(ConnectivityManager::class.java))
}
networkStatusChecker.performIfConnectedToInternet {
activity?.runOnUiThread {
...
}
}
Just like before, open the RemoteApi.kt. First add the following object, at the top of the class:
private val gson = Gson()
You only need to create Gson once, and you can reuse it as many times as you want. Head over to the getTasks, and copy the basic structure as with the other requests. Make sure to change the REST method to GET:
Thread(Runnable {
val connection = URL("$BASE_URL/api/note").openConnection() as HttpURLConnection
connection.requestMethod = "GET"
connection.setRequestProperty("Content-Type", "application/json")
connection.setRequestProperty("Accept", "application/json")
connection.setRequestProperty("Authorization", App.getToken())
connection.readTimeout = 10000
connection.connectTimeout = 10000
connection.doInput = true
connection.disconnect()
}).start()
Notice the combination of the endpoint path, and the requestMethod. You’re using the GET call, as you’ll be fetching data from an endpoint just for notes. Also notice the authorization header which is used to authenticate with the server. For this request you don’t need to send any data, you can just receive it from the API:
Thread(Runnable {
val connection = URL("$BASE_URL/api/note").openConnection() as HttpURLConnection
connection.requestMethod = "GET"
connection.setRequestProperty("Content-Type", "application/json")
connection.setRequestProperty("Accept", "application/json")
connection.setRequestProperty("Authorization", App.getToken())
connection.readTimeout = 10000
connection.connectTimeout = 10000
connection.doInput = true
try {
val reader = InputStreamReader(connection.inputStream)
reader.use { input ->
val response = StringBuilder()
val bufferedReader = BufferedReader(input)
bufferedReader.useLines { lines ->
lines.forEach {
response.append(it.trim())
}
}
}
} catch (error: Throwable) {
}
connection.disconnect()
}).start()
Just like before, you’re consuming all the lines of the response text. Finally, add the following code, to parse the data, and send it to the UI
Thread(Runnable {
val connection = URL("$BASE_URL/api/note").openConnection() as HttpURLConnection
connection.requestMethod = "GET"
connection.setRequestProperty("Content-Type", "application/json")
connection.setRequestProperty("Accept", "application/json")
connection.setRequestProperty("Authorization", App.getToken())
connection.readTimeout = 10000
connection.connectTimeout = 10000
connection.doInput = true
try {
val reader = InputStreamReader(connection.inputStream)
reader.use { input ->
val response = StringBuilder()
val bufferedReader = BufferedReader(input)
bufferedReader.useLines { lines ->
lines.forEach {
response.append(it.trim())
}
}
val tasksResponse = gson.fromJson(response.toString(), GetTasksResponse::class.java)
onTasksReceived(tasksResponse.notes, null)
}
} catch (error: Throwable) {
onTasksReceived(emptyList(), error)
}
connection.disconnect()
}).start()
The Gson object has multiple methods, for parsing from JSON, and serializing to JSON. In this case, you’re saying you want to parse the response, as a String, into a GetTasksResponse.
It will try to parse the data, and translate keys from the JSON String, to the properties within the class. So a “notes” key in JSON, will translate to a “notes” property in the class. And that’s it! Run the project, and you should see notes from the server show up in your app! :]
Because Gson is so convenient, you can replace the following code in the addTask, login and register calls, to match the getTasks call:
val request = gson.toJson(addTaskRequest)
...
val body = gson.toJson(userDataRequest) // login & register
val task = gson.fromJson(response.toString(), Task::class.java)
You could also change the other response parsing, but since they are simple, you can leave them as is. Run the project once again, and things should be working as before! :]