I'm using volley for my post requests and the issue is when I send 362 requests on queue to the server the data will save even though there's an error response as I assumed, or there are repeating data stored in the database.Sometimes my network connectivity is slow. Let's say I send 362 data to my server and I have 3 error response, when the sync was done the overall total of the saved data is still 362 and it should 359 since I have 3 error response, currently I have condition when the error response received the data should not save to the server.
This is what I've tried
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject data = new JSONObject(response);
String status = data.getString("status");
String description = data.getString("description");
JSONObject dataObject = data.getJSONObject("data");
String household = dataObject.getString("hh_id");
if (status.matches("success")){
progressCC[0]++;
progressPercent = findViewById(R.id.progressCount);
progressBar = findViewById(R.id.progressBar);
progressCount = findViewById(R.id.progressFigure);
Double progressCalc = progressCC[0] / countEmvDetails * 100;
progressCount.setText(String.valueOf(progressCC[0].intValue()));
progressPercent.setText(String.valueOf(progressCalc.intValue()));
progressBar.setProgress(progressCalc.intValue());
lst.add(description + "household id: " + household);
gvMain.setAdapter(adapter);
if (progressPercent.getText().toString().matches("100")) {
Toasty.success(SyncData.this, "Completed", Toast.LENGTH_SHORT, true).show();
Toasty.success(SyncData.this, "Updating local data please wait!", Toast.LENGTH_SHORT, true).show();
updaterEmvMonitoring();
}
sqLiteHelper.storeLogs("sync", hh_id);
sqLiteHelper.deleteEmvMonitoringDetails(id);
}
else{
btnSync.setEnabled(true);
lst2.add("Error on syncing the data!");
gvMain2.setAdapter(adapter2);
Toasty.error(getApplicationContext(), "Error on pulling data.", Toast.LENGTH_SHORT, true).show();
}
} catch (JSONException e) {
btnSync.setEnabled(true);
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// method to handle errors.
btnSync.setEnabled(true);
sqLiteHelper.storeLogs("error", hh_id);
try {
String responseBody = new String(error.networkResponse.data, "utf-8");
Integer responseCode = error.networkResponse.statusCode;
if (responseCode == 401) {
JSONObject data = new JSONObject(responseBody);
JSONArray errors = data.getJSONArray("errors");
JSONObject jsonMessage = errors.getJSONObject(0);
String message = jsonMessage.getString("message");
Toasty.warning(SyncData.this, message, Toast.LENGTH_SHORT, true).show();
lst2.add(message);
gvMain2.setAdapter(adapter2);
} else if (responseCode == 404) {
JSONObject data = new JSONObject(responseBody);
String desc = data.getString("description");
Toasty.error(SyncData.this, "Error 404:" + desc, Toast.LENGTH_SHORT, true).show();
lst2.add(desc);
gvMain2.setAdapter(adapter2);
}
} catch (Exception e) {
Log.d("Error co", String.valueOf(e));
lst2.add(String.valueOf(e));
gvMain2.setAdapter(adapter2);
Toasty.error(SyncData.this, "Network not found.", Toast.LENGTH_SHORT, true).show();
}
}
}) {
#Override
public Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + token);
return headers;
}
protected Map<String,String> getParams(){
Map<String, String> params = new HashMap<>();
params.put("full_name", full_name);
return params;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(
DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 5,
0,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);
Related
I send the /getsms GET request to an API and I get the expected results on postman. However, when I try to make the same request through volley in java on android studio, it just doesn't get a response, I keep waiting and nothing happens.
I'm sure the API does get the request since the expected changes occur when I send the data associated with the get request.
So I'm at a loss as to why exactly it doesn't get a response.
Java code:
final String url = "http://10.0.2.2:3000/myroute/getsms/"+frm;
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response) {
try {
String frm = response.getString("src_num");
String msg = response.getString("msg");
int id = response.getInt("id");
itemsAdapter.add(frm + ": " + msg);
Log.d("Response", response.toString());
}
catch (Exception err) {
Log.d("excpetion", err.toString());
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", error.toString());
}
}
);
API code:
router.get('/getsms/:dest_num', function (req, res) {
console.log("get oldest unsent sms from db");
let sql = "SELECT * FROM " + table + " WHERE " + "dest_num=" + req.params.dest_num + " AND sent=FALSE " + "ORDER BY id " + "LIMIT 1;";
console.log(sql);
db.mycon.query(sql, function (err, result) {
console.log("Result: " + JSON.stringify(result));
if(err){
res.send(err);
} else {
console.log("SENT!")
res.json(result);
}
});
});
Any help is appreciated.
UPDATE: So upon sifting through the logs I found this:
2020-01-15 22:07:23.481 11880-11880/com.example.sms D/Error.Response: com.android.volley.ParseError: org.json.JSONException: Value [{"id":4,"src_num":"321","dest_num":"1003435365","msg":"first message from server","time":100,"sent":0}] of type org.json.JSONArray cannot be converted to JSONObject
Apparently the response is received but Volley kicks when parsing. I cant see why this is happening. I don't see anything wrong with the JSON string. And is this really enough for it to not go into the onResponse function?
UPDATE2: So apparently that was indeed the problem and what was sent wasn't a JSONObject but a JSONArray. and just needed to change the datatypes accordingly.
So the code ended working with:
String url = "http://10.0.2.2:3000/myroute/getsms/" + frm;
JsonArrayRequest jsonObjectRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response_arr) {
try {
JSONObject response = response_arr.getJSONObject(0);
String frm = response.getString("src_num");
String msg = response.getString("msg");
int id = response.getInt("id");
itemsAdapter.add(frm + ": " + msg);
} catch (Exception err) {
System.out.println(err.toString());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", error.toString());
}
});
requestQueue.add(jsonObjectRequest);
Thanks to the comments for helping :)
You can try for The code given below and also add the request to the requestqueue of the new instance of RequestHandler.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray array = new JSONArray(response); //here is the mistake of parsing which will be removed after it is converted to the json object
JSONObject object = array.getJSONObject(0); //-----mistake
String frm = object.getString("src_num");
String msg = object.getString("msg");
int id = object.getInt("id");
itemsAdapter.add(frm + ": " + msg);
Log.d("Response", response.toString());
} catch (JSONException e) {
Log.d("excpetion", err.toString());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.response", err.toString());
}
});
new RequestHandler().addToRequestQueue(stringRequest);
Hope it helps !!
I have an API which send me a JSON object when I send a token to the server , I use GET method and I have to send token in body, not headers, it works in postman correctly when I put token in body but I have volley server error in android studio and I entered error response.here is my codes:
ant solution???? please
private void getFreightsFromServer()
{
final String url =" https://parastoo.app/api/driver-cargo-list";
JSONObject jsonData = new JSONObject();
String token = G.getString("token");
try
{
jsonData.put("token", token);
} catch (JSONException e)
{
e.printStackTrace();
}
Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>()
{
boolean isGet = false;
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public void onResponse(JSONObject response)
{
try
{
MyPost post = new MyPost();
JSONArray jsonArray = response.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject tempJsonObject = jsonArray.getJSONObject(i);
JSONObject jsonOriginCustomer = new JSONObject(tempJsonObject.getString("origin_customer"));
post.setOriginCity(jsonOriginCustomer.getString("customerCity"));
JSONObject jsonDestinationCustomer = new JSONObject(tempJsonObject.getString("destination_customer"));
Log.d("result", jsonDestinationCustomer.getString("customerCity"));
post.setDestinationCity(jsonDestinationCustomer.getString("customerCity"));
freightsList.add(post);
// isGet = true;
adapter.notifyDataSetChanged();
}
} catch (JSONException e)
{
e.printStackTrace();
}
}
};
Response.ErrorListener errorListener = new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(getContext(), error.toString(), Toast.LENGTH_LONG).show();
Log.d("jdbvdc", error.toString());
error.printStackTrace();
}
};
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, jsonData, listener, errorListener);
Log.d("fhdhdcf",jsonData.toString());
final int socketTimeout = 100000;
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
request.setRetryPolicy(policy);
AppSingleton.getInstance(getContext()).addToRequestQueue(request);
}
Please show the error message you have. Also I am not sure how ok it is to send something in a body of a GET request. This answer might help you:
HTTP GET with request body
It's better to use post method for this type of request.
But still if you want to use GET method then you should have to pass token in the URL.
Below is an example
final String username = etUname.getText().toString().trim();
final String password = etPass.getText().toString().trim();
URLline = "https://demonuts.com/Demonuts/JsonTest/Tennis/loginGETrequest.php?username="+username+"&password="+password;
I'm trying to send GET request to Wordpress rest api from my Android app.
In postman I send POST and GET request which worked but when I send a request with the same headers I get com.android.volley.AuthFailureError .
Here's my code
public void getSlides(final onSlideReceived onSlideReceived) {
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET,
BASE_URL + "slider", null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Toast.makeText(context, response.toString(), Toast.LENGTH_LONG).show();
Log.i(ITAGSLIDE, "onResponse: "+response);
onSlideReceived.onReceived(slides);
}
} , new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(context, error.toString(), Toast.LENGTH_SHORT).show();
Log.e(ETAGSLIDE, "onErrorResponse: "+error.toString() );
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> headers = new HashMap<>();
Map<String,String> params = new HashMap<>();
params.put("oauth_consumer_key",CONSUMER_KEY);
params.put("oauth_nonce", OAUTH_NONCE);
params.put("oauth_signature_method",OAUTH_SIGNATURE_METHOD);
params.put("oauth_timestamp",OAUTH_TIMESTAMP);
params.put("oauth_token", OAUTH_TOKEN);
params.put("oauth_version",OAUTH_VERSION);
String encodedParams = mapToStringAnd(params);
String string_to_sign = "";
try {
string_to_sign = (new StringBuilder("GET&"))
.append(URLEncoder.encode(
BASE_URL+"slider", "utf-8")).append("&")
.append(URLEncoder.encode(encodedParams, "utf-8")).toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Log.d("string to sign", string_to_sign);
try {
Mac mac = Mac.getInstance("HMAC-SHA1");
String secret = CONSUMER_SECRET + "&" + OAUTH_TOKEN_SECRET;
Log.d("secret", secret);
mac.init(new SecretKeySpec(secret.getBytes("utf-8"), "HMAC-SHA1"));
OAUTH_SIGNATURE = Base64.encodeToString(mac.doFinal(string_to_sign.getBytes("utf-8")), 0).trim();
Log.d("signature", OAUTH_SIGNATURE);
} catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
e.printStackTrace();
}
String query =
"oauth_consumer_key=\""+CONSUMER_KEY+"\""+
",oauth_token=\""+OAUTH_TOKEN+"\""+
",oauth_signature_method=\""+OAUTH_SIGNATURE_METHOD+"\""+
",oauth_timestamp=\""+OAUTH_TIMESTAMP+"\""+
",oauth_nonce=\""+OAUTH_NONCE+"\""+
",oauth_version=\""+OAUTH_VERSION+"\""+
",oauth_signature=\""+OAUTH_SIGNATURE+"\"";
Log.d("query","OAuth "+query);
headers.put("Authorization","OAuth "+query);
return headers;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(18000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(context).add(request);
}
Finally here's my header query which I get in logcat:
OAuth oauth_consumer_key="*****",oauth_token="******",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1545421361",oauth_nonce="8.308277993153459E7",oauth_version="1.0",oauth_signature="*******"
Where is my mistake? How should I send request to get a response?
Thanks a lot for any help.
I have created an API for the purpose to retrieve data from database. Now I able to retrieve status, message and data from the API no matter I input the credentials correct or incorrect. There are two version of output. I used POSTMan to test on and that it seems working but when I try on Android, success message is okay but not the error one.
#POST
#Path("/appdatas")
public Response getSAppData(AppDataRequest adr) {
Response data = ads.getSAppData(adr.getId(), adr.getEmail(), adr.getPassword());
return data;
}
#SuppressWarnings("unchecked")
public Response getSAppData(int id, String email, String password){
Map<String, AppData> AppDataHM = new HashMap<String, AppData>();
Map<String, Data> DataHM1 = new HashMap<String, Data>();
Map<String, List<String>> DataHM2 = new HashMap<String, List<String>>();
Map ADHMDHM = new HashMap<>();
Data data = DataHM.get(new AppDataRequest (id, email, password));
List<String> message = new ArrayList<>();
List<String> data2 = new ArrayList<>();
if(data != null){
message.add("");
AppDataHM.put("AppData", new AppData("success", message));
DataHM1.put("Data", data);
ADHMDHM.putAll(AppDataHM);
ADHMDHM.putAll(DataHM1);
String ADHMDHM1 = new Gson().toJson(ADHMDHM);
return Response.status(200).entity(ADHMDHM1).build();
}
else{
message.add("Your login information is invalid. Please try with the correct information");
AppDataHM.put("AppData", new AppData("error", message));
DataHM2.put("Data", data2);
ADHMDHM.putAll(AppDataHM);
ADHMDHM.putAll(DataHM2);
String ADHMDHM2 = new Gson().toJson(ADHMDHM);
return Response.status(500).entity(ADHMDHM2).build();
}
}
When I use POSTMan, I able to retrieve both output.
{
"AppData": {
"status": "success",
"message": [
""
]
},
"Data": {
"token": "token1"
}
}
{
"AppData": {
"status": "error",
"message": [
"Your login information is invalid. Please try with the correct information"
]
},
"Data": []
}
When I apply the following code on Android, I able to retrieve data for success one but not the error one.
private void makeJsonObjectRequest(){
showpDialog();
String id1 = mEditTextID.getText().toString();
String email1 = mEditTextEmail.getText().toString().trim();
String password1 = mEditTextPassword.getText().toString();
HashMap<String, String> params = new HashMap<String, String>();
params.put("id", id1);
params.put("email", email1);
params.put("password", password1);
JsonObjectRequest request = new JsonObjectRequest(url, new JSONObject(params), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject AppData = response.getJSONObject("AppData");
String status = AppData.getString("status");
String message = AppData.getString("message");
//JSONObject Data = response.getJSONObject("Data");
//String token = Data.getString("token");
jsonResponse = "";
jsonResponse += "Status: " + status + "\n";
jsonResponse += "\n";
jsonResponse += "Message: " + message + "\n";
//jsonResponse += "\n";
//jsonResponse += "Token: " + token + "\n";
mTextViewMain.setText(jsonResponse);
hidepDialog();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getActivity(),
"Error: " + e.getMessage(),
Toast.LENGTH_SHORT).show();
}
hidepDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error1: " + error.getMessage());
Toast.makeText(getActivity(),
"Error2: " + error.getMessage(), Toast.LENGTH_SHORT).show();
hidepDialog();
}
});
AppController.getInstance().addToRequestQueue(request);
}
How possible I can get the output as shown in the 'error' output and display in the TextView?
Thanks for everyone for viewing this question.
Why are you returning status 500 in your script? Volley assumes code 500 as error
return Response.status(500).entity(ADHMDHM2).build();
Try changing it to 200 and check
You can use this link to generate concrete classes for the json. Once you have the concrete classes then you can use GSON to convert json text to class. This way you will have concrete json to class mapping.
May be this can help.
For Message try this:
JSONArray messageArray = AppData.getJSONArray("message");
String message = messageArray.toString();
Hi guys I do not know how to read the actual detailed error message from the server, all I am getting is E/Volley: [73767] BasicNetwork.performRequest: Unexpected response code 500 for https://xxxx.com/xxxxx I saw people adding a onErrorResponse listener but mine isnt working so im clearly missing something, below is my code, any help is appreciated.
Request:
JSONObject jsonFavorites = new JSONObject();
String userId = Integer.toString(2);
String waypointID = Integer.toString(eventInfo.waypointId);
String waypointType = Integer.toString(eventInfo.stopType);
try {
jsonFavorites.put("action", favoriteAction);
jsonFavorites.put("uid", userId);
jsonFavorites.put("waypointid", waypointID);
jsonFavorites.put("waypoint_type", waypointType);
//fetchData(bounds);
} catch (Exception e) {
}
try{
GetUserFavoritesRequest favoritesRequest = new GetUserFavoritesRequest(jsonFavorites, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//Parse the response that was received from the server.
Log.d("Maps:", " Parsing Response");
try {
Log.i("tagconvertstr", "[" + response + "]");
//List<String> allFavorites = new ArrayList<String>();
JSONArray cast = new JSONArray(response);
if(userFavoritewaypointId.contains(eventInfo.waypointId)){
favoriteAction = "remove";
infoFavoriteButton.setImageResource(R.drawable.favorites_disabled);
}else{
favoriteAction = "add";
infoFavoriteButton.setImageResource(R.drawable.favorites);
}
finished = true;
} catch (JSONException e) {
//adding or removing favorites was unsuccessful.
Log.d("Maps:", " Failed getting a response from server for adding or removing favorites");
e.printStackTrace();
//Set the finished flag to true to let everyone know that we
//finished receiving a response from the server.
finished = true;
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Parse the response that was received from the server.
NetworkResponse networkResponse = error.networkResponse;
if (networkResponse != null) {
Log.e("Volley", "Error. HTTP Status Code:"+networkResponse.statusCode);
}
if (error instanceof TimeoutError) {
Log.e("Volley", "TimeoutError");
}else if(error instanceof NoConnectionError){
Log.e("Volley", "NoConnectionError");
} else if (error instanceof AuthFailureError) {
Log.e("Volley", "AuthFailureError");
} else if (error instanceof ServerError) {
Log.e("Volley", "ServerError");
} else if (error instanceof NetworkError) {
Log.e("Volley", "NetworkError");
} else if (error instanceof ParseError) {
Log.e("Volley", "ParseError");
}
Log.d("Maps:", " Error: " + error.getMessage());
finished = true;
}
});
RequestQueue queue = Volley.newRequestQueue(getActivity());
queue.add(favoritesRequest);
} catch (Exception e) {
//We failed to start a login request.
Log.d("Maps:", " Failed to start response for adding or removing favorites");
//Set the finished flag to true to let everyone know that we
//finished receiving a response from the server.
finished = true;
}
GetUserFavoritesRequest.java
public class GetUserFavoritesRequest extends StringRequest {
private static final String LOGIN_REQUEST_URL = "https://xxxx.com/xxxxx";
private Map<String, String> params;
public GetUserFavoritesRequest(JSONObject getFavorites, Response.Listener<String> listener, Response.ErrorListener errorListener){
super(Request.Method.POST, LOGIN_REQUEST_URL, listener, null);
params = new HashMap<>();
try {
if(getFavorites.get("action").toString().equals("get")){
Log.d("Maps: ", "Looks like we are retrieving a list of favorite waypoints");
params.put("action", getFavorites.get("action").toString());
params.put("uid", getFavorites.get("uid").toString());
}else if(getFavorites.get("action").toString().equals("add")){
Log.d("Maps: ", "Looks like we are adding a favorite waypoint" + getFavorites);
params.put("action", getFavorites.get("action").toString());
params.put("uid", getFavorites.get("uid").toString());
params.put("waypointid", getFavorites.get("waypointid").toString());
params.put("waypoint_type", getFavorites.get("waypoint_type").toString());
}else if(getFavorites.get("action").toString().equals("remove")) {
Log.d("Maps: ", "Looks like we are removing a favorite waypoint" + getFavorites);
params.put("action", getFavorites.get("action").toString());
params.put("uid", getFavorites.get("uid").toString());
params.put("waypointid", getFavorites.get("waypointid").toString());
params.put("waypoint_type", getFavorites.get("waypoint_type").toString());
}
}catch (Exception e){
}
}
#Override
public Map<String, String> getParams() {
return params;
}
}
I think there might be a mistake in GetUserFavoritesRequest's constructor
super(Request.Method.POST, LOGIN_REQUEST_URL, listener, null);
change null to errorListener.