How to correctly do array request in volley - kotlin

I'm trying to do get request and get array in json but i'm having error like this:
org.json.JSONException: Value [] of type org.json.JSONArray cannot be converted to JSONObject
here's my request code:
private fun getStudents(endLink: String) {
val request = JSONObject()
val studentLink = "https://192.168.1.1/getStudents.php?idEntity="
val linkFull = studentLink.plus(endLink)
val jsArrayRequest = JsonObjectRequest(Request.Method.GET, linkFull, request, Response.Listener<JSONObject> {
val builder = GsonBuilder()
val gson = builder.create()
val student =
gson.fromJson<Students>(it.toString(), students::class.java!!)
studentResponse = studentResponse
//updateInfo()
}, Response.ErrorListener {
Log.d("ERRORKA", it.message)
Toast.makeText(
this.context,
it.message, Toast.LENGTH_SHORT
).show()
})
MySingleTon.getInstance(this.context!!).addToRequestQue(jsArrayRequest)
}
also my data models:
class StudentResponse {
var groupNumber: String = ""
var students: List<Students>? = null
}
here's 2nd:
class Students {
val id: Int = 0
val firstName: String? = ""
val lastName: String? = ""
val middleName: String? = ""
val email: String? = ""
}

You are not doing jsonArrayRequest, you can see the object you are creating is of JsonObjectRequest. Do like below.
// Method: POST
val mDataArray = JSONArray(); // This should be JSONArray object
val mRequest = JsonArrayRequest(Request.Method.POST,"YOUR API URL", mDataArray,{
//Response listener
},{
//Error listener
})
// Method: GET
val mRequest = JsonArrayRequest(Request.Method.GET,"YOUR API URL", null,{
//Response listener
},{
//Error listener
})

Related

io.ktor.client.features.ClientRequestException: Client request invalid

When calling the getUser function, I make an HTTP request that retrieves information about a user.
If the user does not exist I get the error:
io.ktor.client.features.ClientRequestException: Client request(https://api.intra.chocolat.fr/v2/users/fff) invalid: 404 Not Found. Text: "{}"
I am unable to catch the error, and to continue the execution of the program.
package com.ksainthi.swifty.api
import android.util.Log
import androidx.annotation.Keep
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.features.*
import io.ktor.client.features.json.*
import io.ktor.client.features.json.serializer.*
import io.ktor.client.features.observer.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.*
import kotlinx.serialization.*
class Api42Service {
#Keep
#Serializable
data class Token(
#SerialName("access_token") val accessToken: String,
#SerialName("token_type") val tokenType: String,
#SerialName("expires_in") val expiresIn: Int,
#SerialName("scope") val scope: String,
#SerialName("created_at") val createdAt: Int
)
#Keep
#Serializable
data class User(
#SerialName("id") val id: Int,
#SerialName("email") val email: String,
#SerialName("login") val login: String? = null,
#SerialName("first_name") val firstName: String? = null,
#SerialName("last_name") val lastName: String? = null,
)
private var accessToken: String? = null
private var client: HttpClient = HttpClient() {
install(JsonFeature) {
serializer = KotlinxSerializer(kotlinx.serialization.json.Json {
prettyPrint = true
isLenient = true
ignoreUnknownKeys = true
})
}
}
private val API_URL: String = "https://api.intra.chocolat.fr"
private val API_SECRET: String =
"<secret>"
private val API_UID: String =
"<api_uid>"
suspend fun requestAPI(
requestMethod: HttpMethod,
path: String,
params: MutableMap<String, String>?
): HttpResponse {
val urlString = API_URL
.plus(path)
return client.request(urlString) {
method = requestMethod
params?.forEach { (key, value) ->
parameter(key, value)
}
headers {
accessToken?.let {
println(it)
append(HttpHeaders.Authorization, "Bearer $it")
}
}
}
}
suspend fun getToken(): Token {
val params: MutableMap<String, String> = HashMap()
params["grant_type"] = "client_credentials";
params["client_secret"] = API_SECRET;
params["client_id"] = API_UID;
val response = requestAPI(HttpMethod.Post, "/oauth/token", params);
val token: Token = response.receive()
accessToken = token.accessToken
return token
}
suspend fun getUser(login: String): User? {
try {
val response = requestAPI(HttpMethod.Get, "/v2/users/$login", null);
val user: User = response.receive()
return user
} catch (cause: io.ktor.client.features.ClientRequestException) {
Log.d("wtf", "Catch your error here")
}
return null
}
}

Not able to return a desired value inside a overidden method using coroutines in kotlin

I am new to kotlin and coroutines.I have been working on a client-server part of an android app.I am using mediasoup-client-android library for this.
I am trying to intialize the sendtransports using createSendTransport() method.This method does have a sendTransportListener which has abstract methods.One of them being is onProduce() which returns a producerId which is a String. awaitEmit() is an asynchronous action and I need this in onProduce().To use awaitEmit() I used coroutines.But I need String as return type instead of Deferred.Is there any other way to implement the mentioned logic? Below is my code
class RoomClient {
suspend fun initTransports(device: Device) {
coroutineScope {
val id: String?
val iceParameters: String?
val iceCandidates: String?
val dtlsParameters: String?
val sctpParameters: String?
try {
val params = JSONObject()
params.put("forceTcp",false)
params.put("rtpCapabilities", this#RoomClient.device?.rtpCapabilities)
val res = socket?.awaitEmit("createWebRtcTransport",params)
val data = res?.get(0) as JSONObject
if (data.has("error")) {
Log.d(TAG, data.getString("error"))
return#coroutineScope
}
id = data.optString("id")
iceParameters = data.optString("iceParameters")
iceCandidates = data.optString("iceCandidates")
dtlsParameters = data.optString("dtlsParameters")
sctpParameters = data.optString("sctpParameters")
} catch (e: Throwable) {
Log.e(TAG, "${e.message}")
return#coroutineScope
}
val sendTransportListener: SendTransport.Listener = object : SendTransport.Listener {
private val listenerTAG = TAG.toString() + "_ProducerTrans"
override fun onProduce(
transport: Transport,
kind: String?,
rtpParameters: String?,
appData: String?
): String? {
this#coroutineScope.async{
var producerId: String? = null
Log.d(listenerTAG, "onProduce() ")
val producerDeferred = launch {
val params = JSONObject("""{"producerTransportId": transport.id, "kind": kind, "rtpParameters": rtpParameters,"appData": appData}""")
val res = socket?.awaitEmit("produce",params)
val data = res?.get(0) as JSONObject
producerId = data.getString("producer_Id")
}
producerDeferred.join()
Log.d(listenerTAG, "producerId inside the coroutine: $producerId"
}
return#async producerId
}
}
this#RoomClient.producerTransport = device.createSendTransport(
sendTransportListener, id,
iceParameters,
iceCandidates,
dtlsParameters
)
}
}
}
And also I am not sure about the way coroutines are used here.Please correct me If I have missed something central.

Problem with volley POST and response null from the server (Kotlin)

I got a problem with my Volley POST in kotlin :
When I use this following code, my application go on "Response.Listener", but the array is null, so when I try to display the information I've just send, I can only get "null".
May you guys help me? :)
There is the kotlin code :
private fun sendHtmlRequest(view: View){
val emailreq = view?.findViewById<EditText>(R.id.editText_email)
val pwdreq = view?.findViewById<EditText>(R.id.editText_password)
val email = emailreq.text.toString()
val pwd = pwdreq.text.toString()
val jsonobj = JSONObject()
var url = "https://www.dorian-roulet.com/testStage-master/mobileApp/testpostone.php"
jsonobj.put("mail", email)
jsonobj.put("pwd", pwd)
val que = Volley.newRequestQueue(context)
val req = JsonObjectRequest(Request.Method.POST, url, jsonobj,
Response.Listener { response ->
view.findViewById<TextView>(R.id.error_login)?.text = ("Ca marche $response $jsonobj")
println("Yessai")
}, Response.ErrorListener{
view.findViewById<TextView>(R.id.error_login)?.text = ("Ca marche pas mec $jsonobj")
println("Erreur")
}
)
que.add(req)
}
Now, there is the PHP code :
<?php
$reponse = array("mail" => $_POST["mail"], "pwd" => $_POST["pwd"]);
echo json_encode($reponse);
?>
I tried to use a GET to recieve this data from a GET array, but the problem still being...
And when I go on my server's logs, I cans ee that I have a POST request from my application (even if I can't see what's in the request).
I use this code to do a Login task, but atm, I just want to send a post request from my application.
Please help :)
EDIT: Your PHP code is NOT fine.
To get JSON data you should not use $_POST (even if it was send with post). Use this instead:
<?php
$data = json_decode(file_get_contents('php://input'), true);
$reponse = array("mail" => $data["mail"], "pwd" => $data["pwd"]);
echo json_encode($reponse);
?>
Here is a code that work for volley (it's not too different than what you have :-) ):
val jsonObjectRequest: JsonObjectRequest = object : JsonObjectRequest(Method.POST, url, **jsonobj**, Response.Listener { response: JSONObject ->
try {
val email = response.getString("email")
val password = response.getString("password")
} catch (e: JSONException) {
// catch/handle JSON error
} catch (e: Exception) {
// catch/handle other error
}
}, Response.ErrorListener { error: VolleyError ->
//Error Listener code
}) {
override fun getBodyContentType(): String {
return "application/x-www-form-urlencoded"
}
// you can override more functions here if needed (getHeader, etc.)
}
queue.add(jsonObjectRequest)
For your case it would likely give:
private fun sendHtmlRequest(view: View){
val emailreq = view?.findViewById<EditText>(R.id.editText_email)
val pwdreq = view?.findViewById<EditText>(R.id.editText_password)
val email = emailreq.text.toString()
val pwd = pwdreq.text.toString()
val jsonobj = JSONObject()
var url = "https://www.dorian-roulet.com/testStage-master/mobileApp/testpostone.php"
jsonobj.put("mail", email)
jsonobj.put("pwd", pwd)
val que = Volley.newRequestQueue(context)
val req = JsonObjectRequest(Request.Method.POST, url, jsonobj,
Response.Listener { response: JSONObject ->
val mailBack = response.getString("mail")
val pwdBack = response.getString("pwd")
view.findViewById<TextView>(R.id.error_login)?.text = ("Ca marche $response $mailBack - $pwdBack")
println("Yessai")
}, Response.ErrorListener{
view.findViewById<TextView>(R.id.error_login)?.text = ("Ca marche pas mec $jsonobj")
println("Erreur")
}
)
que.add(req)
}
There is the code I have after you send me what code I have to put inside :
(Still returns null values)
private fun sendHtmlRequest(view: View){
val emailreq = view?.findViewById<EditText>(R.id.editText_email)
val pwdreq = view?.findViewById<EditText>(R.id.editText_password)
val email = emailreq.text.toString()
val pwd = pwdreq.text.toString()
val jsonobj = JSONObject()
var url = "https://www.dorian-roulet.com/testStage-master/mobileApp/testpostone.php"
jsonobj.put("mail", email)
jsonobj.put("pwd", pwd)
val que = Volley.newRequestQueue(context)
val jsonObjectRequest = JsonObjectRequest(
Request.Method.POST, url, jsonobj,
Response.Listener { response: JSONObject ->
val emails = response.getString("mail")
val passwords = response.getString("pwd")
view.findViewById<TextView>(R.id.error_login)?.text = ("Ca marche $emails $passwords $response $jsonobj")
}, Response.ErrorListener {
view.findViewById<TextView>(R.id.error_login)?.text = ("Ca marche pas mec $jsonobj")
println("Erreur")
}) /*{
override fun getBodyContentType(): String {
return "application/x-www-form-urlencoded"
}
// you can override more functions here if needed (getHeader, etc.)
}*/
que.add(jsonObjectRequest)
}

Get response from server in JWT

I have the following code, where I validate the JWT token (with volley):
private fun validateToken(token: String) {
var queue = Volley.newRequestQueue(this)
val yourUrl = "https://mysite/wp-json/jwt-auth/v1/token/validate"
val parameters = JSONObject()
try {
parameters.put("username", "abc#test.com")
parameters.put("password", "12345678")
} catch (e: java.lang.Exception) {
}
val request: JsonObjectRequest =
object : JsonObjectRequest(
Method.POST, yourUrl, parameters,
Response.Listener { response -> Log.i("onResponse", response.toString()) },
Response.ErrorListener { error -> Log.e("onErrorResponse", error.toString()) }) {
#Throws(AuthFailureError::class)
override fun getHeaders(): Map<String, String> {
val headers: MutableMap<String, String> = HashMap()
// Basic Authentication
//String auth = "Basic " + Base64.encodeToString(CONSUMER_KEY_AND_SECRET.getBytes(), Base64.NO_WRAP);
headers["Authorization"] = "Bearer $token"
return headers
}
}
queue.add(request)
}
It works for me and I get the correct response from the server (in Log.i):
{"code":"jwt_auth_valid_token","data":{"status":200}}
My question is how in my code I do to be able to save the status: 200 in a variable so then it applies an ʻif status == 200` and if it is 200 then send it to another activity.
Add implementation 'com.google.code.gson:gson:2.8.6' to build.gradle(app)
Create Model.tk with:
data class dataServer (
#SerializedName("code") val code : String,
#SerializedName("data") val data : Data
)
data class Data (
#SerializedName("status") val status : Int
)
3. Update code:
private fun validateToken(token: String) {
var queue = Volley.newRequestQueue(this)
val yourUrl = "https://myweb/wp-json/jwt-auth/v1/token/validate"
val parameters = JSONObject()
try {
parameters.put("username", "abc#test.com")
parameters.put("password", "12345678")
} catch (e: java.lang.Exception) {
}
val request: JsonObjectRequest =
object : JsonObjectRequest(
Method.POST, yourUrl, parameters,
Response.Listener {
response ->
Log.i("onResponse", response.toString())
val gson = Gson()
val dataToken = gson.fromJson(response.toString(), dataServer::class.java)
val status = dataToken.data.status
println(status)
// use here if then
},
Response.ErrorListener { error -> Log.e("onErrorResponse", error.toString()) }) {
#Throws(AuthFailureError::class)
override fun getHeaders(): Map<String, String> {
val headers: MutableMap<String, String> = HashMap()
// Basic Authentication
//String auth = "Basic " + Base64.encodeToString(CONSUMER_KEY_AND_SECRET.getBytes(), Base64.NO_WRAP);
headers["Authorization"] = "Bearer $token"
return headers
}
}
queue.add(request)
}

How to return a String from a Kotlin method?

I am new to Kotlin. I am simply trying to return a response as a String from a method. But if I use val Str = ""; it is not re-assignable.
Like Java in why can't we re-assign a response to a String which is defined already, and return it.
public fun getCustomers(): String {
val Str = null;
val StringRequest = StringRequest(Request.Method.GET, url, Response.Listener<String> { response ->
Str = response.toString();
}, Response.ErrorListener {
it.printStackTrace();
})
return Str;
}
Use var for the Str variable that you have used here because val is like final, and you can't re-assign it.
public fun getCustomers(): String {
var Str = "";
val StringRequest = StringRequest(Request.Method.GET, url, Response.Listener<String> { response ->
Str = response.toString();
}, Response.ErrorListener {
it.printStackTrace();
})
return Str;
}
private val customers: String get() {
var Str = "";
val StringRequest = StringRequest(Request.Method.GET, url, Response.Listener<String> { response ->
Str = response.toString();
}, Response.ErrorListener {
it.printStackTrace();
})
return Str;
}