I am using the strava API for an app. I am making synchronous requests as can be seen by the code below.
try {
RequestQueue queue = Volley.newRequestQueue(context);
RequestFuture<String> future = RequestFuture.newFuture();
StringRequest request = new StringRequest(Request.Method.GET, urlRequest, future, future);
queue.add(request);
dataResponse = dealWithResponse(future.get());
} catch (ExecutionException e) {
System.err.println(e.getLocalizedMessage());
System.err.println(e.getMessage());
System.err.println(e.toString());
} catch (java.lang.Exception e) {
e.printStackTrace();
}
I want to know how can I get the response code in the event of an error? for example some rides I request have been deleted / are private and i receive a 404 error code. Other times I have run out of API requests and get a code of 403. How can i differentiate between the thrown errors.
Thank you very much for your help!
In your catch clause, where you handle the ExecutionException you can add the following:
if (e.getCause() instanceof ClientError) {
ClientError error = (ClientError)e.getCause();
switch (error.networkResponse.statusCode) {
//Handle error code
}
}
Override parseNetworkError on your request:
StringRequest request = new StringRequest(Request.Method.GET, urlRequest, future, future) {
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
if (volleyError != null && volloeyError.networkResponse != null) {
int statusCode = volleyError.networkResponse.statusCode;
switch (statusCode) {
case 403:
// Forbidden
break;
case 404:
// Page not found
break;
}
}
return volleyError;
}
};
Related
I have such an OkHttp code to retreive data from OpenWeather API:
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new okhttp3.Request.Builder().url(url).build();
AsyncTask.execute(() -> {
Response response = null;
try {
response = okHttpClient.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
if(response.code() == 200) {
Log.d("weather", "200");
JSONArray array;
try {
JSONObject mObj = new JSONObject(response.body().string());
array = mObj.getJSONArray("weather");
widgetView.setTextViewText(R.id.weatherTextView, array.getJSONObject(0).getString("main"));
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
It's located in my Widget class in void updateWidget, which is called from onUpdate() void. But the problem is that this OkHttp code just doesn't get executed.
What can cause this problem?
I developed a service, using resttemplate and using this service(clientproject) in another project(server), I am trying to throw the exception from resttemplate and handle at server project,but it is not working.
Here is my code:
public class UserService{
public long createUser(Long servcieId){
long userId =0L;
try
{
response = restTemplate.exchange(url,HttpMethod.POST, request, Object.class);
userId = response.getBody().getUser().getId();
}
catch(RestClientException e){
throw e;
}
return userId;
}
}
Here is my service code:
public Long createUserInPortal(Long serviceId){
try
{
Long userId=userService.createUser(serviceId);
}
catch(RestClientException e){
if(e instanceof HttpStatusCodeException){
String errorResponse=((HttpStatusCodeException)e).getResponseBodyAsString();
logger.error("the error in user service is:"+errorResponse);
}
}
I am getting the following error,"resulted in 422 (Unprocessable Entity); invoking error handler".
I am trying to see the response string in the catch block but it is not reaching this catch block.
well may be its getting inside catch block but gets filtered by
if(e instanceof HttpStatusCodeException){ condition
May be e instance is not of type HttpStatusCodeException there are other possibilities like
} catch (HttpClientErrorException e) {
success = false;
Log.e(TAG, command+" was rejected for URL: "+url, e);
resultCode = e.getStatusCode().value();
response = e.getResponseBodyAsString();
} catch (HttpServerErrorException e) {
success = false;
Log.e(TAG, command+" could not be completed for URL: "+url, e);
resultCode = e.getStatusCode().value();
response = e.getResponseBodyAsString();
} catch (ResourceAccessException e) {
if (attemptsLeft > 0) {
Log.w(TAG, command+" failed I/O, retrying.", e);
return simplePut(baseUrl, url, b, command, payload, attemptsLeft);
}
success = false;
Log.e(TAG, command+" failed I/O for URL: "+url, e);
resultCode = 499;
} catch (RestClientException e) {
success = false;
Log.e(TAG, command+" failed for URL: "+url, e);
resultCode = 599;
}
I have a Volley request, and I'm trying to get the results set in a variable, but I get the error "Variable 'stuff' is accessed from inner class, needs to be declared final." The problem is, once I declare it as final, I'm not allowed to set the variable equal to the response (like I'm trying to in the try block). I've looked around for the other questions that discuss this, but none have really been helpful to my situation.
Here is the code:
public ArrayList getStuff() {
ArrayList<JSONObject> stuff;
new Thread(new Runnable() {
#Override
public void run() {
// Instantiate the RequestQueue.
RequestQueue queue = MySingleton.getInstance(getApplicationContext()).getRequestQueue();
String url ="http://localhost:6000/stuff";
RequestFuture<String> future = RequestFuture.newFuture();
// Testing out blocking
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, future, future);
// Add the request to the RequestQueue.
queue.add(stringRequest);
try {
String response = future.get(30, TimeUnit.SECONDS);
stuff = response;
Log.i("tutors after blocked: ", tutors);
} catch(InterruptedException e) {
e.printStackTrace();
} catch(ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}).start();
// I want to be able to return 'stuff' here
return stuff;
}
Just add the word final as indicated below.
public ArrayList getStuff() {
final ArrayList<JSONObject> stuff; <--Add final here
new Thread(new Runnable() {
#Override
public void run() {
// Instantiate the RequestQueue.
RequestQueue queue = MySingleton.getInstance(getApplicationContext()).getRequestQueue();
String url ="http://localhost:6000/stuff";
RequestFuture<String> future = RequestFuture.newFuture();
// Testing out blocking
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, future, future);
// Add the request to the RequestQueue.
queue.add(stringRequest);
try {
String response = future.get(30, TimeUnit.SECONDS);
stuff = response;
Log.i("tutors after blocked: ", tutors);
} catch(InterruptedException e) {
e.printStackTrace();
} catch(ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}).start();
// I want to be able to return 'stuff' here
return stuff;
}
Just move that variable declaration outside the method. this means it is already a Global Variable of that class
ArrayList<JSONObject> stuff;
public ArrayList getStuff() {
new Thread(new Runnable() {
#Override
public void run() {
// Instantiate the RequestQueue.
RequestQueue queue = MySingleton.getInstance(getApplicationContext()).getRequestQueue();
String url ="http://localhost:6000/stuff";
RequestFuture<String> future = RequestFuture.newFuture();
// Testing out blocking
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, future, future);
// Add the request to the RequestQueue.
queue.add(stringRequest);
try {
String response = future.get(30, TimeUnit.SECONDS);
stuff = response;
Log.i("tutors after blocked: ", tutors);
} catch(InterruptedException e) {
e.printStackTrace();
} catch(ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
}).start();
// I want to be able to return 'stuff' here
return stuff;
}
After digging so much I got something in my mind that SharedPreferences,
If you really want response data outside , You can use SharedPreferences to store the response value in some variable and read the same value outside whenever you want.
To set value to the variable
String MyPREFERENCES = "MyPrefs";
SharedPreferences.Editor editor = context.getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE).edit();
editor.putString("returnResponse", "success");
editor.apply();
To get value of the variable
String return_value = sharedpreferences.getString("returnResponse", "");
I'm using Volley StringRequest to post a query to my server and I seeing that in about 20% of cases, the request is successful but onErrorResponse is called instead of onResponse.
Here is my request code:
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("App", "[MainActivity] post successful");
// run very important routine only when post is successful
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("App", "[MainActivity] failed to post");
if (error == null) {
Log.e("App", "no error");
}
else if (error.networkResponse != null) {
Log.e("App", String.valueOf(error.networkResponse.statusCode));
if(error.networkResponse.data != null) {
try {
Log.e("App", new String(error.networkResponse.data, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
else {
Log.e("App", "no network response");
}
}
});
requestQueue.add(stringRequest);
20% of the time I see:
E/App: [MainActivity] failed to post
E/App: no network response
but in my server logs I see a 200 message and the data created by the post is in my database.
Why would Volley throw an error on a successful post?
UPDATE
Log.e("App", "error message: " + error.getMessage());
prints: E/App: error message: null
What is the error message returned by volley? Check it by volleyError.getMessage().
I have an android app that most of its feature consumes an API. My client complained that the retrieving of data from the web api is very slow. I wonder what's causing this.
Here's a basic structure of how I do my calls:
String returnString = "";
token = tokenBuilder.generateToken("Customers/All");
try {
HttpGet request = new HttpGet(apiUrl + "CustomerRewards/All?customerId=" + id);
request.setHeader(HTTP.CONTENT_TYPE, "application/json");
request.setHeader("AccountId", headerAccountId);
request.setHeader("StoreId", headerStoreId);
request.setHeader("AppKey", headerAppKey);
request.setHeader("Token", token);
HttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(request);
String responseString = EntityUtils.toString(response.getEntity());
Log.i("Api Message", responseString);
returnString = responseString;
} catch (Exception e) {
returnString = e.getMessage();
}
return returnString;
I'm calling this method from a progress dialog in order to display a loader while, retrieving data from the web API. Is there a better way to do this? Or is somewhat my android code affects its performance?
Here's the code on the calling progress dialog.
rewardsErrorMessage = "";
progressBar = new ProgressDialog(this);
progressBar.setCancelable(true);
progressBar.setMessage("Loading info ...");
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressBar.setProgress(0);
progressBar.setMax(100);
progressBar.setCancelable(false);
progressBar.show();
apiLoadStatus = false;
new Thread(new Runnable() {
public void run() {
while (!apiLoadStatus) {
apiLoadStatus = RewardApi();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (apiLoadStatus) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progressBar.dismiss();
}
}}).start();
progressBar.setOnDismissListener(new OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
SetValues();
}
});
And here's the method that actually calls the api class that connects to the web api
ApiConnection api = new ApiConnection();
try {
Log.i("CustomerId", customerInfos.getString("customer_id", ""));
transactionMessage = api.GetTransactions(customerInfos.getString("customer_id", ""));
availableRewardsMessage = api.GetCustomerRewards(customerInfos.getString("customer_id", ""));
try
{
if(transactionMessage.contains("Timestamp"))
{
Log.i("Transaction", "Success");
GetPoints(transactionMessage);
}
if(!availableRewardsMessage.equals("[]") && !availableRewardsMessage.equals("[]"))
{
JSONObject rewardsJson = new JSONObject(availableRewardsMessage);
availableRewardsMessage = rewardsJson.getString("AvailableRewards");
hasRewards = true;
}
return true;
}
catch(Exception e)
{
rewardsErrorMessage = transactionMessage.replace('[', ' ').replace(']', ' ').replace('"', ' ');
}
} catch(Exception e) {
e.printStackTrace();
rewardsErrorMessage = e.getMessage();
return true;
}
return true;
As you notice, I have two api calls here.
I really would like to speed up the retrieving of data. Or is the api I'm consuming that slow? Any ideas guys? Thanks!
As you're probably aware, there are a number of factors that can affect HTTP service calls, of which the client code is only one:
Network speed and latency
Server availability and load
Size of data payload
Client device resources
Client code
You really need to determine where the bottleneck(s) are in order to know where to try to optimize. Additionally, you should make sure that the server is using Gzip to compress the payload and add the following to your client code:
request.setHeader("Accept-Encoding", "gzip");