Kotlin-Volley Send JSON (post) with multiple json object in json array - json

i am build Point Of Sales apps and i can’t able to send multiple json object in json array. My apps read from android database (SQLite) and send multiple products to server. anyone help me ? thanks
Logcat : E/Volley: [893] BasicNetwork.performRequest: Unexpected response code 422 for https://…
override fun getHeaders(): MutableMap<String, String> {
val headers = HashMap<String, String>()
headers["Accept"] = "application/json"
headers["Content-Type"] = "application/x-www-form-urlencoded"
headers["Authorization"] = "Bearer " + user_info.token
return headers
}
override fun getParams(): MutableMap<String,String> {
val cartRepository = CartRespository(application)
val transaksi = cartRepository.getByIdTrans(id_trans)
val jo = JSONObject()
val ja = JSONArray()
for(i in 0 until transaksi.size){
ja.put(i,jo.put("product_id", transaksi[i].id_item))
ja.put(i,jo.put("jumlah", transaksi[i].kuantitas).toString())
}
val map = HashMap<String, String>()
map.put("rfid", "122312")
map.put("device", user_info.device)
map.put("products", ja.toString())
return map
}
this is my request API body, run normaly in postman.
{
"rfid": "122312",
"device": "1233311",
"products": [
{
"product_id": 4,
"jumlah": "1"
}
]
}

Related

Nested JSON Objects in Kotlin with Volley

I am very new to this as you can probably tell, but i'm trying to parse a JSON url with Volley using Kotlin in Android Studio. The url contains nested Objects, not nested Arrays.
I can display everything inside "questionnaire", but I only want to display "typeOfQuestion". How do i do that?
MainActivity.kt:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
questionTV = findViewById(R.id.idTVQuestion)
answerTV = findViewById(R.id.idTVAnswer)
typeTV = findViewById(R.id.idTVType)
val queue: RequestQueue = Volley.newRequestQueue(applicationContext)
val request = JsonObjectRequest(Request.Method.GET, url, null, { response ->
loadingPB.setVisibility(View.GONE)
try {
val question: String = response.getString("question")
val answer: String = response.getString("answer")
val typeOfQuestion: String = response.getString("typeOfQuestion")
questionTV.text = question
answerTV.text = answer
typeTV.text = typeOfQuestion
} catch (e: Exception) {
e.printStackTrace()
}
}, { error ->
Log.e("TAG", "RESPONSE IS $error")
Toast.makeText(this#MainActivity, "Fail to get response", Toast.LENGTH_SHORT)
.show()
})
queue.add(request)
}
}
Heres the JSON:
{
"questionnaire": {
"question": "Where do you live?",
"answer": "In the mountains",
"typeOfQuestion": "Informative
}
}
You have object inside another json object.If you need to access field from child object you need to get child jsonObject and then get fields from object.
var questionnaire = response.getJSONObject("questionnaire")
You need to get fields from questionnaire object.Like.
val question: String = questionnaire.getString("question")
val answer: String = questionnaire.getString("answer")
val typeOfQuestion: String = questionnaire.getString("typeOfQuestion")

serialize a json using gson

I am using com.google.gson.JsonObject to send the json inside 'parameters' to a rest endpoint.
{
"parameters":
"{
\"customer\" : {
\"firstName\": \"Temp\",
\"lastName\": \"Temp\",
\"emailAddresses\": [\"temp1#temp.com\"],
\"address\": {
\"street1\": \"123 W Temp St\",
\"city\": \"Temp\",
\"state\": \"Illinois\",
\"zipCode\": \"61122\"
}
},
\"options\" : [\"tv\"]
}"
}
Since Parameters is a json string, I am trying to do this :
JsonObject json = new JsonObject();
json.addProperty("options", ??);
I am not sure how to do it for customer and options.
'options' is a java Set, whereas customer is an object.
You may use:
Gson gson = new Gson();
String json = "{\"parameters\": {\"customer\" ... ";
JsonObject jsonObject = gson.fromJson(json, JsonObject.class);
JsonArray options = new JsonArray();
options.add("tv");
jsonObject.add("options", options);
String output = gson.toJson(jsonObject);

Post Request in Kotlin

I'm trying to do a post request in Android Studio written in Kotlin
I'm posting a JSON object to our server and then the server is returning a JSON object back. But what I'm doing here is decoding the response body as a string and then converting it into the data structure we need. I'm sure there is a better and simpler way to do what I need done.
My current code works but the major issue I'm having is formatting the string if our objects have nested objects which is why I want to figure out a better way to turn the response body into a json object.
I'm not too familiar with many request libraries for kotlin but I have looked into okhttp3 but I'm not sure how to post a json object, attach headers and decode the response body into a json object.
I know for okhttp3 I need to convert the json object to a string to post other than that I'm lost.
Breakdown of what's needed:
Post JSON Object To Server
Send Headers With Post Request
Decode Response Body into JSON Object/ Kotlin Equivalent
Simplify What I'm Trying to Do if Possible
This is the current code I have
private fun postRequestToGetDashboardData() {
val r = JSONObject()
r.put("uid", muid)
r.put("token", mtoken)
SendJsonDataToServer().execute(r.toString());
}
inner class SendJsonDataToServer :
AsyncTask<String?, String?, String?>() {
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
if (result.equals(null)) {
val t = Toast.makeText(this#Home, "No devices to display", Toast.LENGTH_LONG)
t.setGravity(Gravity.CENTER, 0, 0)
t.show()
} else {
intentForUnique.putExtra("FirstEndpointData", result)
var list = handleJson(result)
adapter.submitList(list)
dashboardItem_list.adapter = adapter
adapter.notifyDataSetChanged();
dashboardItem_list.smoothScrollToPosition(0);
}
}
override fun doInBackground(vararg params: String?): String? {
val JsonDATA = params[0]!!
var urlConnection: HttpURLConnection? = null
var reader: BufferedReader? = null
try {
val url = URL("URL");
urlConnection = url.openConnection() as HttpURLConnection;
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Authorization", mtoken);
urlConnection.setRequestProperty("Accept", "application/json");
val writer: Writer =
BufferedWriter(OutputStreamWriter(urlConnection.getOutputStream(), "UTF-8"));
writer.write(JsonDATA);
writer.close();
val inputStream: InputStream = urlConnection.getInputStream();
if (inputStream == null) {
return null;
}
reader = BufferedReader(InputStreamReader(inputStream))
var inputLine: String? = reader.readLine()
if (inputLine.equals("null")) {
return null
} else {
return inputLine
}
} catch (ex: Exception) {
Log.e(TAG, "Connection Failed", ex);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (ex: Exception) {
Log.e(TAG, "Error closing stream", ex);
}
}
}
return null
}
}
private fun handleJson(jsonString: String?): ArrayList<SensorData> {
val jsonArray = JSONArray(jsonString)
val list = ArrayList<SensorData>()
var x = 0
while (x < jsonArray.length()) {
val jsonObject = jsonArray.getJSONObject(x)
list.add(
SensorData(
jsonObject.getInt("deviceId"),
// jsonObject.getString("deviceName"),
jsonObject.getInt("battery"),
jsonObject.getString("dateTime"),
jsonObject.getInt("airValue"),
jsonObject.getInt("waterValue"),
jsonObject.getInt("soilMoistureValue"),
jsonObject.getInt("soilMoisturePercent")
)
)
x++
}
return list
}
So the json data being returned back is an array of this structure (our backend is written in Go)
type Device struct {
DeviceID int `bson:"deviceId" json:"deviceId"`
Battery int `bson:"battery" json:"battery"`
DateTime time.Time `bson:"dateTime" json:"dateTime"`
AirValue int `bson:"airValue" json:"airValue"`
WaterValue int `bson:"waterValue" json:"waterValue"`
SoilMoistureValue int `bson:"soilMoistureValue" json:"soilMoistureValue"`
SoilMoisturePercent int `bson:"soilMoisturePercent" json:"soilMoisturePercent"`
}

How to add Body request in url in Kotlin?

Here is my Code that for Volley Request:-
val searchRequest = object : JsonArrayRequest(Request.Method.GET,url,
Response.Listener { response ->
val result = response.toString()
},
Response.ErrorListener { error ->
Toast.makeText(activity, "Error!",Toast.LENGTH_LONG)
.show()
Log.d("ERROR",error.toString())
})
{
override fun getBody(): ByteArray {
// TODO add Body, Header section works //////////
return super.getBody()
}
override fun getBodyContentType(): String {
return "application/json"
}
override fun getHeaders() : Map<String,String> {
val params: MutableMap<String, String> = HashMap()
params["Search-String"] = songName
params["Authorization"] = "Bearer ${accessTx.text}"
return params
}
}
AppController.instance!!.addToRequestQueue(searchRequest)
I want to add this information in the body section
video_id = "BDJIAH" , audio_quality = "256"
here is the sample to add above information in the below segment.
{ "video_id":"ABCDE", "audio_quality":"256" }
Basically, I am facing problem in ByteArray section. That doesn't work for me.
You can use toByteArray() method of String class in Kotlin.
For example:
val charset = Charsets.UTF_8
val byteArray = "SomeValue".toByteArray(charset)
Also try to pass multiple values in the request body in this way:
val requestBody = "video_id = "+"ABCDE"+ "& audio_quality ="+ "256"
val charset = Charsets.UTF_8
val byteArray = requestBody.toByteArray(charset)

Access to JSON element in groovy map

I'm trying to access an element of some json returned into a map from an api call so I can pass it to another api call. I can't seem to properly create a varible and give it the value I need. Here's the returned json, I need to access the Id element.
{
"totalSize": 1,
"done": true,
"records": [
{
"attributes": {
"type": "User",
"url": "/services/data/v24.0/sobjects/User/MYIDNUMBER"
},
"Id": "MYIDNUMBER"
}
]
}
here's the restful service call I use and my attempt to access the Id element and put it in sfId so I can use it in my next API call
def http = new HTTPBuilder(instance_domain)
http.request(GET,JSON) { req ->
uri.path = "services/data/v24.0/query/"
uri.query = [q:"SELECT Id from User WHERE Email = '$loginid#myschool.edu'"]
headers['Authorization'] = "Bearer $access_token"
response.success = { resp, json ->
json.each{ key,value ->
sfMap = [sfUser: [json: json]]
}
sfId = sfMap[records.Id]
}
response.failure = { resp, json ->
println resp.status
println json.errorCode
println json.message
}
}
I get the following error on the server where the portletized version of this is deployed
2014-07-08 08:02:39,710 ERROR [http-bio-443-exec-161] portal-web.docroot.html.portal.render_portlet_jsp:154 groovy.lang.MissingPropertyException: No such property: records for class: groovyx.net.http.HTTPBuilder$RequestConfigDelegate
Based on your json structure, here's what I can say. The records is an array which potentially can contain number of objects hence number of Ids.
def json = new groovy.json.JsonSlurper().parseText ("""
{
"totalSize": 1,
"done": true,
"records": [
{
"attributes": {
"type": "User",
"url": "/services/data/v24.0/sobjects/User/MYIDNUMBER"
},
"Id": "MYIDNUMBER"
}
]
}
""")
If you are sure about first element's Id, then this will do the trick:
println json.records.first().Id
Otherwise, this might be better option which will give you Ids of all the objects in records.
println json.records.collect{ it.Id }
#kunal, that helped.
For future refernce, here's how I added the delcaration of a varible to be used later on, assigning it the value from the json responce.
def http = new HTTPBuilder(instance_domain)
http.request(GET,JSON) { req ->
uri.path = "services/data/v24.0/query/"
uri.query = [q:"SELECT Id from User WHERE Email = '$loginid#myschool.edu'"]
headers['Authorization'] = "Bearer $access_token"
response.success = { resp, json ->
sfId = json.records.first().Id <----- this did the trick
json.each{ key,value ->
sfMap = [sfUser: [json: json]]
}
}
response.failure = { resp, json ->
println resp.status
println json.errorCode
println json.message
}
}