Android Volly Parsing Error for Nested JSONObject - android

I am trying to post Json data via Android Volly library but getting an error.
Here is my Json body which perfectly working with Postman.
{
"fullName": "Mr X",
"fatherName": "Mr Y",
"motherName": "Mrs Z",
"nidNo": "34345",
"surveyDate": "2020-03-25",
"birthCertificateNo": "3435355",
"mobileNumber": "01834261758",
"dateOfBirth": "",
"gender": "Male",
"bloodGroup": "A+",
"numOfDaysSick": "23",
"numOfContInftPerson": "0",
"remarks": "Need Rest",
"physicalSymptoms": ",Runny nose,Sore throat",
"status": "User",
"isForeignVisitor": "false",
"isRead": "false",
"presentAddress": {
"village": "Sonapur",
"postOffice": "Noahat",
"postCode": "1219",
"upazila": "Sonaimuri",
"district": "Noakhali",
"division": "Chittagong"
},
"permanentAddress": {
"village": "Sonapur",
"postOffice": "Noahat",
"postCode": "1234",
"upazila": "Sonaimuri",
"district": "Noakhali",
"division": "Chittagong"
}}
But when i try to send it via Android Volly's Post call I am getting the error below :
com.android.volley.ParseError: org.json.JSONException: Value Survey of type java.lang.String cannot be converted to JSONObject
Here is my Android method to generate this Json body.
Note that : I can successfully generate Json body with this Android method and copy paste(from Logcat) to Postman, it works fine. But Android Volly giving me such error. My url is also ok because I tested it manually.
public void SendSurveyDataToServer(){
customProgressBar.show();
//--
//-------------------------------
JSONObject permanent_address = new JSONObject();
try {
permanent_address.put("village", village_pS);
permanent_address.put("postOffice", post_office_pS);
permanent_address.put("postCode", post_code_pS);
permanent_address.put("upazila", upazilla_pS);
permanent_address.put("district", district_pS);
permanent_address.put("division", division_pS);
} catch (JSONException e) {
e.printStackTrace();
}
//--
JSONObject present_address = new JSONObject();
try {
present_address.put("village", village_tS);
present_address.put("postOffice", post_office_tS);
present_address.put("postCode", post_code_tS);
present_address.put("upazila", upazilla_tS);
present_address.put("district", district_tS);
present_address.put("division", division_tS);
} catch (JSONException e) {
e.printStackTrace();
}
//--
if(numberofContactedPersonS.equals("Yes")){
numberofContactedPersonS = "true";
}else{
numberofContactedPersonS = "false";
}
//--
//--
JSONObject parameters = new JSONObject();
try {
parameters.put("fullName", fullNameS);
parameters.put("fatherName", fatherNameS);
parameters.put("motherName", motherNameS);
parameters.put("nidNo", nidNoS);
parameters.put("surveyDate", "2020-03-25");
parameters.put("birthCertificateNo", birthdayCertificateNoS);
parameters.put("mobileNumber", mobileNoS);
parameters.put("dateOfBirth", "");
parameters.put("gender", gender_selectS);
parameters.put("bloodGroup", blood_group_selectS);
parameters.put("numOfDaysSick", sickDaysNoS);
parameters.put("numOfContInftPerson", "0");
parameters.put("remarks", remarksS);
parameters.put("physicalSymptoms", physicalSymptomsS);
parameters.put("status", statusS);
parameters.put("isForeignVisitor", numberofContactedPersonS );
parameters.put("isRead", "false");
parameters.put("presentAddress", present_address);
parameters.put("permanentAddress", permanent_address);
} catch (JSONException e) {
e.printStackTrace();
}
Log.d(classTag,parameters.toString());
RequestQueue rq = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.POST, ApiClass.server_path+ApiClass.saveSurvey, parameters, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
String respo=response.toString();
Log.d(classTag,respo);
//iosDialog.cancel();
//Parse_signup_data(respo);
Log.e(classTag,respo);
if(respo.equalsIgnoreCase("Survey Info save Successfully")){
Toast.makeText(Survey.this,"Your survey submitted successfully. Thank you!",Toast.LENGTH_LONG).show();
//----------------------------------------
}else if(respo.equalsIgnoreCase("Survey Info already exits")){
Toast.makeText(Survey.this,"Survey info already exist with this NID and Birth Certificate Number!",Toast.LENGTH_LONG).show();
}else{
Toast.makeText(Survey.this,"There is an error while submitting your survey, please try again!",Toast.LENGTH_LONG).show();
Log.e(classTag,"There is an error while submitting your survey, please try again!");
}
customProgressBar.hide();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
// Toast.makeText(MainActivity.this,"Can't connect with server! Please check your network connection.",Toast.LENGTH_LONG).show();
customProgressBar.hide();
Log.d(classTag,error.toString());
}
});
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(30000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
rq.getCache().clear();
rq.add(jsonObjectRequest);
//--------------
}

After searching for 3 days I found that the problem is API response. It was giving me 'Success' and 'Failed' in byte format but I was always checking the response for JSONObject or at least String. Postman converted the byte data into string automatically and showed me, for that reason I thought server was giving me the response in string format.
However, I sent the Json request by Volly's String Request and track the response. Then I found what is messing with me! Our backend developer might be lazy to give a response in String or Json format.
I got the response by converting byte to string :
String string = new String(response.data, StandardCharsets.UTF_8);
Here is my modification for this :
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = ApiClass.server_path+ApiClass.saveSurvey;
final String requestBody = parameters.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
customProgressBar.hide();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
customProgressBar.hide();
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
//customProgressBar.hide();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
String string = new String(response.data, StandardCharsets.UTF_8);
Log.e(classTag,string);
serverMsg = string;
showServerMsgNow = true;
Log.e(classTag,"Server msg : "+serverMsg+" server show : "+showServerMsgNow);
// ShowServerResponse();
}
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);

Related

How should i get the data from sourceJson in android using volley?

Below is the response what i am getting i want to get the data from "SourceJson" m not ble to understnd why i am getting "" in source json please help me
{
"incomingOrder": [
{
"Namw": 8510,
"Surname": "00",
"mob": "00",
"phone": "000",
"SourceJson": "{\"cart_gst\":30.21,\"instructions\":\"\",\"order_packing_charges\":30,\"cart_igst_percent\":0,\"cart_sgst\":15.1038,}",
"test": "NotSynced",
"test": "DPA",
}]}
Try this code :
requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest obreq = new JsonObjectRequest(Request.Method.GET, JsonURL,
// The third parameter Listener overrides the method onResponse() and passes
//JSONObject as a parameter
new Response.Listener<JSONObject>() {
// Takes the response from the JSON request
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("incomingOrder");
JSONObject jsonObject = jsonArray.getJSONObject(0);
JSONObject objSourceJson=jsonObject.getJSONObject("SourceJson");
Log.i("IvaSourceJson",objSourceJson.toString());
String cart_gst=objSourceJson.getString("cart_gst");
String instructions=objSourceJson.getString("instructions");
}
// Try and catch are included to handle any errors due to JSON
catch (JSONException e) {
// If an error occurs, this prints the error to the log
e.printStackTrace();
}
}
},
// The final parameter overrides the method onErrorResponse() and passes VolleyError
//as a parameter
new Response.ErrorListener() {
#Override
// Handles errors that occur due to Volley
public void onErrorResponse(VolleyError error) {
Log.e("Volley", "Error");
}
}
);
// Adds the JSON object request "obreq" to the request queue
requestQueue.add(obreq);
As it is JSONArray data is of list type, better not to use jsonArray.getJSONObject(0);.
Use this code for multiple results,
StringRequest request = new StringRequest(Request.Method.GET, "", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("Response", response);
try {
JSONObject object = new JSONObject(response);
JSONArray array = object.getJSONArray("incomingOrder");
for (int i = 0; i < array.length(); i++){
JSONObject object1 = array.getJSONObject(i);
String name = object1.getString("Namw");
String surname = object1.getString("Surname");
String mob = object1.getString("mob");
String phone = object1.getString("phone");
String sourceJson = object1.getString("SourceJson");
String test = object1.getString("test");
String test1 = object1.getString("test");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error", error.getMessage());
}
});
Context context;
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.add(request);
Code this in any method and call the method where the action needed.

Parsing Json object received from rest api

I am using Volley library to execute my rest APIs.
Using this I have sent email, password entries to URL and receiving response in JSON as:
{
"success": true,
"data": {
"message": false,
"token": "some token value"
}
}
Now I want to parse the 'token' field received from response and do further action. How can this be parsed?
This is the function where I want to parse the response.
public void parseData(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getString("success").equals("true")) {
Toast.makeText(MainActivity.this,"UserExists",Toast.LENGTH_LONG).show();
////RETRIEVE "token" HERE
else {
Toast.makeText(MainActivity.this,"User not registered",Toast.LENGTH_LONG).show();
}
I have seen this link How to parse JSON Object Android Studio but my "token" field is within another object, so not sure how to do it.
if you want to parse JSON in same manual way you have to do like this to get token.
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getBoolean("success")== true) {
Toast.makeText(MainActivity.this, "UserExists", Toast.LENGTH_LONG).show();
JSONObject dataObj= jsonObject.getJSONObject("data");
String token= dataObj.getString("token");
////RETRIEVE "token" HERE
} else {
Toast.makeText(MainActivity.this, "User not registered", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
Here is the solution
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
JSONObject dataObj = response.getObject("data");
String token = dataObj.getString("token");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
}
);
Please use POJO for parsing. Otherwise you will take more time to do this kind of work.
If you are using Volley, why not simply use the JsonObjectRequest:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Request.Method.GET,
url,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// parse the response
JSONObject data= response.getObject("data");
String token = data.getString("token");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
}
);
MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
You can try like following.
public void parseData(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getString("success").equals("true")){
Toast.makeText(MainActivity.this,"UserExists",Toast.LENGTH_LONG).show();
////RETRIEVE "token" HERE
JSONObject dataObject = jsonObject.getObject("data");
String token = dataObject.getString("token");
}
else {
Toast.makeText(MainActivity.this,"User not registered",Toast.LENGTH_LONG).show();
}
}catch(JSONException e) {
Log.e("YourTAG","exceptions "+e.toString());
}
Hope it helps you.

post request with passing list in body using volley

i have created spring boot api and now i am integrating it with android app in post request i pass a list while testing from postman and it worked well but it did not work while i send list from android. please tell me how to send a list in a body of json with volley library this is image of postman
this is my code
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
JSONObject jsonBody = new JSONObject();
List<Integer> ids=new ArrayList<>();
ids.add(11);
ids.add(12);
jsonBody.put("ids",ids);
final String mRequestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_ADD_SKILLS, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("LOG_RESPONSE", response);
}
}, error -> Log.e("LOG_VOLLEY", error.toString())) {
#Override
public String getBodyContentType() {
return "application/json";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return mRequestBody == null ? null : mRequestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mRequestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
because you are passing wrong json format to post API like below.
{
"ids": "[11, 12]"
}
but in postman you are passing jsonarray ids in object.
{
"ids":[11,12]
}
so make change in your code like this
JSONObject jsonBody = new JSONObject();
JSONArray jArrIds=new JSONArray();
jArrIds.put(11);
jArrIds.put(12);
jsonBody.put("ids",jArrIds);

Get the header value from the android volley [duplicate]

This question already has answers here:
Getting headers from a response in volley
(2 answers)
Closed 6 years ago.
Can someone please guide me that how to get the header value from the url. I have referred to many tutorials but i could not find any tutorial to get the header value from json. Any help would be highly appreciated.
Here is my code:
JsonArrayRequest obreq = new JsonArrayRequest(Request.Method.GET, JsonURL,
// The third parameter Listener overrides the method onResponse() and passes
//JSONObject as a parameter
new Response.Listener<JSONArray>() {
// Takes the response from the JSON request
#Override
public void onResponse(JSONArray response) {
pbHeaderProgress.setVisibility(View.GONE);
try {
// Retrieves the string labeled "colorName" and "description" from
//the response JSON Object
//and converts them into javascript objects
for (int i = 0; i < response.length(); i++) {
JSONObject jresponse = response.getJSONObject(i);
String id = jresponse.getString("id");
Id.add(id);
String auth = jresponse.getString("DJ_author_name");
Author.add(auth);
String date = jresponse.getString("date_gmt");
SimpleDateFormat form = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
java.util.Date date4 = null;
try {
date4 = form.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
Date.add(newDateStr);
JSONObject title = jresponse.getJSONObject("title");
String tit = title.getString("rendered");
Title.add(tit);
JSONObject img = jresponse.getJSONObject("better_featured_image");
String pic = img.getString("source_url");
Image.add(pic);
}
// Adds strings from object to the "data" string
linear.setVisibility(RelativeLayout.VISIBLE);
// Adds the data string to the TextView "results"
adapter.notifyDataSetChanged();
}
// Try and catch are included to handle any errors due to JSON
catch (JSONException e) {
// If an error occurs, this prints the error to the log
e.printStackTrace();
}
}
},
// The final parameter overrides the method onErrorResponse() and passes VolleyError
//as a parameter
new Response.ErrorListener() {
#Override
// Handles errors that occur due to Volley
public void onErrorResponse(VolleyError error) {
pbHeaderProgress.setVisibility(View.GONE);
Toast.makeText(Home.this, "error!!! =)",
Toast.LENGTH_SHORT).show();
noi.setVisibility(RelativeLayout.VISIBLE);
Log.e("Volley", "Error");
}
}
);
obreq.setRetryPolicy(new DefaultRetryPolicy(
30000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// Adds the JSON object request "obreq" to the request queue
requestQueue.add(obreq);
You can subclass Request (or any of its subclasses) and override the parseNetworkResponse method:
#Override
protected Response<Bitmap> parseNetworkResponse(NetworkResponse response)
{
Map<String, String> responseHeaders = response.headers;
}
with reference to this stackoverflow's link
please check djodjos answer here
if you mean you want to get the header values of the json that is returned itself, not the headers of the request itself you can use Gson library it's fast reliable and very easy to use
------- Ok then as djodjos answer
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
JSONObject jsonResponse = new JSONObject(jsonString);
jsonResponse.put("headers", new JSONObject(response.headers));
return Response.success(jsonResponse,
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
} }
you need to override parseNetworkResponse when you create the new JsonArrayRequest (obreq )
for example
StringRequest request=new StringRequest(GET,"url",listener,errorListener){
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String totalPages=responseHeaders.get("X-WP-TotalPages");
return super.parseNetworkResponse(response);
}
};

How to post JSON data using volley library?

I have following format of posting data to server. I want to post these data to server using volley library and following request contains multiple images' base64 content also. I am passing this as StringRequest i got the error of invalid JSON data format. How can i post following data to server? Or any other useful way to pass following data to server then also let me know. So that i can solve this problem and efficiently can upload on server.
{
"TakeoffID": "2",
"ViewPhoto1": "image base64 content",
"ViewPhoto2": "image base64 content",
"LineItems": [
{
"OrderLineid": "964",
"OrderLinePhoto1": "image base64 content",
"OrderLinePhoto2": "image base64 content"
},
{
"OrderLineid": "963",
"OrderLinePhoto1": "image base64 content",
"OrderLinePhoto2": "image base64 content"
}
]
}
===========
Following is my code to upload above data:
private void uploadImage(final CustomerBean bean,final String line_items)
{
// Showing the progress dialog
final ProgressDialog loading = ProgressDialog.show(mActivity, "Uploading...", "Please wait...", false, false);
StringRequest stringRequest = new StringRequest(com.android.volley.Request.Method.POST, Const.API_SYNC_ALL_DATA, new Response.Listener<String>() {
#Override
public void onResponse(String s)
{
loading.dismiss();
Log.print("======UPLOAD IMAGE=====", s);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError)
{
loading.dismiss();
Toast.makeText(mActivity, volleyError.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError
{
Map<String, String> params = new Hashtable<String, String>();
params.put("TakeoffID", "2");
params.put("ViewPhoto1", bean.photo1);
params.put("ViewPhoto2", bean.photo2);
params.put("LineItems", line_items);
// returning parameters
return params;
}
};
// Creating a Request Queue
RequestQueue requestQueue = Volley.newRequestQueue(mActivity);
// Adding request to the queue
requestQueue.add(stringRequest);
}
===========================
And I am getting following error from server.
[
{
"code": "-1",
"message": "The json data format is incorrect"
}
]
You can also use following block of code for pass json object to Volley as a parameter. Just check it once.
JSONObject data= new JSONObject();
data.accumulate("username", "mobileGps");
data.accumulate("password", "9565551236");
JSONObject total= new JSONObject();
total.put("data",data);
json = jsonObjectNew.toString();
IMO, you can refer to my following sample code:
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "http://...";
// Prepares POST data...
JSONObject jsonBody = new JSONObject();
jsonBody.put("TakeoffID", "2");
jsonBody.put("ViewPhoto1", "image base64 content");
jsonBody.put("ViewPhoto2", "image base64 content");
// "OrderLineid": "964"...
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("OrderLineid","964");
jsonObject1.put("OrderLinePhoto1","image base64 content");
jsonObject1.put("OrderLinePhoto2","image base64 content");
// "OrderLineid": "963"...
JSONObject jsonObject2 = new JSONObject();
jsonObject2.put("OrderLineid","963");
jsonObject2.put("OrderLinePhoto1","image base64 content");
jsonObject2.put("OrderLinePhoto2","image base64 content");
JSONArray jsonArray = new JSONArray();
jsonArray.put(jsonObject1);
jsonArray.put(jsonObject2);
// "LineItems"...
jsonBody.put("LineItems", jsonArray);
final String mRequestBody = jsonBody.toString();
// Volley request...
StringRequest request = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return mRequestBody == null ? null : mRequestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
mRequestBody, "utf-8");
return null;
}
}
};
requestQueue.add(request);
} catch (JSONException e) {
e.printStackTrace();
}
Hope it helps!

Categories

Resources