Android async httpclient: how to intercept authentication failures in one place? - android

I have the following mental model that for my android app, all authentication failures should be handled in a single place and the login screen should interrupt and be flashed on top of the view stack to allow the user to reauthenticate.
Not sure how to do this with AsyncHTTPClient.
I do not want to keep handling the 401 and 404 requests for every single GET and POST request that I make. Sounds like a lot of repeated code. So for google and CNN, for example, if I am not authenticated, I don't want to repeat the code to handle the 401 not authenticated code for both CNN and google because it's the same exact code.
Thank you!
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
System.out.println(response);
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable
error)
{
error.printStackTrace(System.out);if 401, TELL USER he has to log in again
}
});
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.cnn.com", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
System.out.println(response);
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable
error)
{
error.printStackTrace(System.out);if 401, TELL USER he has to log in again
}
});

create your own subclass for AsyncHttpResponseHandler and implement the onFailure alone; Add all your failure handling logic in there.
Use this subclass for your client.get instead of AsyncHttpResponseHandler, just implementing the onSuccess.
client.get("http://www.cnn.com", new MyAsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
System.out.println(response);
}
// onFailure handled by common code in MyAsyncHttpResponseHandler
}

Related

getting error "java.net.ConnectException: Failed to connect to" when i m trying API on android device. But it is working on "Postman"

i am trying to call certain API, which is working fine if i test it on laptop(postman) but when i use it in my app its gives exception.
RequestParams params = new RequestParams();
params.add("comapanyName",jsonObject.getString("company_name"));
AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
asyncHttpClient.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
asyncHttpClient.post(url, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
String s = new String(responseBody);
Log.i("RESPONSE_INSERT", s);
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.i("RESPONSE_ERROR_I", e.getMessage());
}
});
Its not local API but on server
Did you add your internet permissions in your Manifest file?
<uses-permission android:name="android.permission.INTERNET" />

LoopJ AndroidAsyncHttp didn't go to onSuccess() or onFailure()

I used LoopJ AndroidAsyncHttp to get the response from the url, but the code didn't go into onSuccess() or onFailure(). The code is as below:
public void queryTopic(RequestParams params) {
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://192.168.0.109:8080/PhoneServer/topic/query", params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
System.out.println("It's in onSuccess");
}
// When the response returned by REST has Http response code
// other than '200'
#Override
public void onFailure(int statusCode, Throwable error,
String content) {
System.out.println("It's in onFailure");
}
});
System.out.println("It's over");
}
It just printed out the "It's over". What's the matter with the AsyncHttpClient?
How are you calling this? Is the context alive? If you are calling it from some place where context is no more available, then you will never get this callbacks.
I think you should try calling this queryTopic() method on click of some button and then wait for some time, you should get the response.
maybe the problem is that you ask to the server for a String
public void onSuccess(String response){...}
but server answer with a JSONObject
You can try this code:
AsyncHttpClient client = new AsyncHttpClient();
client.setTimeout(5000);
client.get(yourActivity.class, yourLink, new JsonHttpResponseHandler(){
#Override
public void onStart() {
Log.e(TAG, "start");
}
#Override
public void onSuccess(int status, Header[] headers, JSONObject answer) {
Log.e(TAG, "SUCCESS");
Log.e(TAG, "print => "+answer.getString("answer_id")); //"answer_id" is a random example
}
#Override
public void onFailure(int status, Header[] headers, String answer, Throwable throwable) {
Log.e(TAG, "FAILURE");
}
});
onSuccess() is an overloaded method be careful regarding what you send from server,
if it is a jsonObject or jsonArray or simple string. Use corresponding overloaded method of onSuccess(). I am using it too for a jsonObject response and i confront no error or irregularities in the method.
I return jsonObject from server for which my code works as expected and is as follows:
RequestParams params = new RequestParams();
params.put("pet","Cat");
params.put("name","Maran");
RestClient.get("/savelocation", params, new JsonHttpResponseHandler(){
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
Toast.makeText(context,response.toString(),Toast.LENGTH_SHORT).show();
Log.e("Error makerequest","request completed");
}
#Override
public void onFinish() {
//onLoginSuccess();
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable,JSONObject errorResponse){
Toast.makeText(context,throwable.toString(),Toast.LENGTH_LONG).show();
}
});
Note: RestClient is a static instance of AsyncHttpClient

android - GET-request with Loopj

I need to make GET-request to a url consisting JSON-data and try to use Loopj library, but it returnes nothing. I tried to find examples on the Internet but they turned out, maybe, to be obsolete (onSuccess method had different parameters). I tried to adapt my code to that example and what I got:
String AllData=""; AsyncHttpClient client = new AsyncHttpClient();
client.get("wantedUrl", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
for (byte aResponseBody : responseBody) {
AllData += aResponseBody;
}
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Toast.makeText(getApplicationContext(),"We got an error",Toast.LENGTH_SHORT).show();
}
});
"wantedUrl" is the url with json, but "AllData" remains empty. How to fix it?
You're getting AsyncHttpResponseHandler callback where you're in need of JsonHttpResponseHandler. Use below code to get the things right on track.
String AllData=""; AsyncHttpClient client = new AsyncHttpClient();
client.get("wantedUrl", new JsonHttpResponseHandler(){
#Override
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
super.onSuccess(statusCode, headers, response);
//Here response will be received in form of JSONArray
}
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
//Here response will be received in form of JSONObject
}
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
super.onFailure(statusCode, headers, responseString, throwable);
Toast.makeText(getApplicationContext(), "We got an error", Toast.LENGTH_SHORT).show();
}
});

Paypal Future Payments: What HTTP requests do I send on the mobile device (Android)?

The Paypal Future Payments demo is pretty thorough, but I'm still a bit confused on what to send from the mobile application.
private void sendAuthorizationToServer(final PayPalAuthorization authorization) {
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("auth", authorization.toJSONObject());
client.post("https://api.sandbox.paypal.com/v1/payments/payment", params,
new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Log.i("success:", String.valueOf(responseBody));
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.i("err:", String.valueOf(error));
}
}
);
What URL do i put
public void onFuturePaymentPurchasePressed(View pressed) {
// Get the Client Metadata ID from the SDK
String metadataId = PayPalConfiguration.getClientMetadataId(this);
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("metaId", metadataId);
client.post("https://api.sandbox.paypal.com/v1/payments/payment", params,
new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Log.i("success:", String.valueOf(responseBody));
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.i("err:", String.valueOf(error));
}
}
);
}
I apologize if you feel this to be evident in the documentation. I have just been struggling for the past couple of days trying to find out what to put as the HTTP request.
The implementation of sendAuthorizationToServer() should post the authorization response to your servers, NOT to PayPal servers. Once the authorization response is received from your app, your server should do the token exchanges described here. The resulting token(s) may then be used to create payments (for which your user has consented to) from your server.
At some point in the future when a purchase is initiated within your mobile app, your app should get Client Metadata ID and send it to your server for inclusion when creating the payment request, as described here.
Hope this helps.

Multiple Callback Design Pattern?

this question is more design related. Am using the Android Async-Http-Client library http://loopj.com/android-async-http/ to make multiple call request from different methods in a class so my code is something like this
RestClient.post(context, "", entity, "application/json", new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
}
#Override
public void onSuccess(int statusCode, Header[] headers, JSONArray timeline) {
// Map objects from json using gson
}
});
if different methods in my classes making similar calls like the code Above but with different request params, how can i encapsulate the ResponseHandler Callback so i don't have to keep repeating it in every method call. Was wondering if there is any other nice design pattern method i can use here.
Note
i have thought of subclassing it and as others have suggested, but i can't seem to get the json object response that way.
Thanks
Is the callback behavior identical across all of these requests? If so, you could either create a single shared instance of JsonHttpResponseHandler and use that everywhere:
private JsonHttpResponseHandler handler = new JsonHttpResponseHandler() {
#Override
public void onSuccess(...) {
...
}
}
...
RestClient.post(..., handler);
or you could create a subclass of JsonHttpResponseHandler and use that:
public class MyResponseHandler extends JsonHttpResponseHandler {
#Override
public void onSuccess(...) {
...
}
}
...
RestClient.post(..., new MyResponseHandler());
You dont have to create a new handler for every call.
JsonHttpResponseHandler myHandler = new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
}
#Override
public void onSuccess(int statusCode, Header[] headers, JSONArray timeline) {
// Map objects from json using gson
}
};
RestClient.post( context, "", entity, "application/json", myHandler );
How about extracting it as a method:
private void restClients(RestClient restClient){
restClient.post(context, "", entity, "application/json", new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
}
#Override
public void onSuccess(int statusCode, Header[] headers, JSONArray timeline) {
// Map objects from json using gson
}
});
}
Then simply calling the method:
restClients(restclient1)

Categories

Resources