How do I parse through JSON Arrays in Kotlin

旧巷老猫 提交于 2021-01-29 12:44:22

问题


so I am working on an Android app and I need to get a list of users from my mysql database and put their data into a User class in my kotlin app.

The php api is working correctly and I get this response with Postman in JSON:

{
    "id": "5f69bbc1b264c6.07041576",
    "username": "Test F",
    "email": "test@gmail.com",
    "profileimagepath": "../uploads/profileimages/5f69bbc1b264c6.07041576.jpg"
}{
    "id": "5f69c5708632f7.37478122",
    "username": "Test H",
    "email": "test@gmail.com",
    "profileimagepath": "../uploads/profileimages/5f69c5708632f7.37478122.jpg"
}

The user class in kotlin looks like this:

class UserItem(val id: String, val username: String, val email: String){
    constructor(): this("","","")
}

And the response listener for the https request looks like this:

val request = JsonObjectRequest(Request.Method.POST,url,jsonObject,
            Response.Listener { response ->
                // Process the json
                try {
                    Log.d("loadTag", response.toString())
                    if(response.getString("error") == "false"){
                        Toast.makeText(applicationContext, "Loading completed!", Toast.LENGTH_SHORT).show()
                    }
                    else if(response.getString("error") == "true" && response.getString("message") == "Invalid code"){
                        Toast.makeText(applicationContext, "Invalid code.", Toast.LENGTH_LONG).show()
                    }
                    else if(response.getString("error") == "true" && response.getString("message") == "Required Parameters are missing"){
                        Toast.makeText(applicationContext, "Invalid user details or fields are empty.", Toast.LENGTH_LONG).show()
                    }
                    else if(response.getString("error") == "true"){
                        Toast.makeText(applicationContext, "Error. Something went wrong. Please try again.", Toast.LENGTH_LONG).show()
                    }

                }catch (e:Exception){
                    Toast.makeText(applicationContext, "Something went wrong. Please try again.", Toast.LENGTH_LONG).show()
                }

            }, Response.ErrorListener{
                // Error in request
                Toast.makeText(applicationContext, "Error in http request. Please contact the developer.", Toast.LENGTH_LONG).show()
            })

I've tried so many things that I've read here and on other posts but I always only get one row (user "Test F")

Update using Jackson

I still get only one of the users using this code

when {
                        response.getString("error") == "true" && response.getString("message") == "Required Parameters are missing" -> {
                            Toast.makeText(applicationContext, "Invalid user details or fields are empty.", Toast.LENGTH_LONG).show()
                        }
                        response.getString("error") == "true" -> {
                            Toast.makeText(applicationContext, "Something went wrong. Please try again.", Toast.LENGTH_LONG).show()
                        }
                        else -> {
                            val mapper = ObjectMapper()
                            val users: UserItem = mapper.readValue(response.toString(), UserItem::class.java)
                            System.out.println(users)
                            Toast.makeText(applicationContext, "Loading completed.", Toast.LENGTH_LONG).show()
                        }
                    }

I get my json response from the api through this code:

$stmt2 = $this->con->prepare("SELECT id,username,email FROM accounts WHERE id=?");
                $stmt2->bind_param("s", $friendsArray2);
                if($stmt2->execute()){
                    $result2 = $stmt2->get_result();
                    $num_of_rows2 = $result2->num_rows;
                    while($row2 = mysqli_fetch_assoc($result2)){
                        $index++;
                        $index2++;
                        echo json_encode($row2);
                    }
                }

There is more code but this is the part that gives me the response as I want the rows found in the sql statement


回答1:


Haven't used PHP for a while, but if I understand correctly you want to serve the array of Objects as Json.

$stmt2 = $this->con->prepare("SELECT id,username,email FROM accounts WHERE id=?");
$stmt2->bind_param("s", $friendsArray2);
if($stmt2->execute()){
    $result2 = $stmt2->get_result();
    $num_of_rows2 = $result2->num_rows;
    $result_array = array();
    while($row2 = mysqli_fetch_assoc($result2)){
        $index++;
        $index2++;
        result_array[] = $row2;
    }

    echo json_encode(result_array);  // echo or do whatever with the encoded json
}

This will push all the row data to the array, and finally will encode the data as a proper Json representation, then will echo (output) to the console/server.

And then you can easily decode the JsonArray into list using kotlinx.serialization:

@Serializable 
data class Project(val id: String, val username: String, val email: String)

// response <= the Json response body, you get from HTTP response
val list: List<UserItem> = JSON.parse(UserItem.serializer().list, response)



回答2:


Use Jackson to parse the JSON into an object, using ObjectMapper.readValue()

See here

https://mkyong.com/java/jackson-how-to-parse-json/

Whilst you're at it, use a when in Kotlin rather than a load of nested if statements.

Updated answer, with example:

import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue

fun main() {

    val json = """
        [{
            "id": "5f69bbc1b264c6.07041576",
            "username": "Test F",
            "email": "test@gmail.com",
            "profileimagepath": "../uploads/profileimages/5f69bbc1b264c6.07041576.jpg"
        },{
            "id": "5f69c5708632f7.37478122",
            "username": "Test H",
            "email": "test@gmail.com",
            "profileimagepath": "../uploads/profileimages/5f69c5708632f7.37478122.jpg"
        }]
    """.trimIndent()

    val mapper = jacksonObjectMapper()
    val userItems : List<UserItem> = mapper.readValue(json)

    println(userItems)
}

data class UserItem(val id: String, val username: String, val email: String,val profileimagepath: String)



回答3:


You can make the UserItem to be a data class instead:

data class UserItem(
    val id: String,
    val username: String,
    val email: String
)

And then use Gson library to convert JSON string into an array of objects:

import com.google.gson.Gson

val json = "{...}"
val response = Gson().fromJson(json, Array<UserItem>::class.java)


来源:https://stackoverflow.com/questions/64042170/how-do-i-parse-through-json-arrays-in-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!