How to receive confirmation in Volley or Retrofit? - java

I want to post some data to a MySQL database. The server-side code will determine whether the data is valid and respond with that determination. Upon receiving this response, the application-side code must decide if it needs to try again or continue on. I have tried callbacks, RequestFuture, and spin-waiting, but it is starting to seem like this type of functionality is not possible with Volley (making decisions based on the server response). Has anyone else had success in implementing this type of functionality?
Main Thread
postCampaign(campaign);
if (//data was invalid) {
//do postCampaign(campaign) again
}
Main Thread
private void postCampaign(final Campaign campaign) {
campaign.setRoomCode("XXXXXXXX");
StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// I want to make a decision based on response
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
...
}
}
) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
// put data
return params;
}
};
NetworkController.getInstance(this).addToRequestQueue(request);
}

from server side, you need to grab the data send by your app. Then you need to check for validations like is the passed data empty/incorrect(incase of passwords check for it against the password in database if its the correct one or not).
In the server side validation of your data, if the data is successfully validated and updated in database then give a success response with proper response code or else if database updation is failed, then give an error response with proper error response code. You may pass these response as a json format to the client(or in whatever format you are comfortable parsing)
Now in the app side you may have a response callback method(available in retrofit/volley). From the response obtained in this callback check if it is a success response or failure response and make appropriate decisions for success/ failure cases

Related

How can I make my code a synchronous POST volley request?

I'm building a tracking app for exercise. As the gps updates every 1 second, the latitude and longitude is added to an array. At the end of the exercise, when you press save, below method is executed, sending all co-ordinates to a database. Because it's an asynchronous request, the co-ordinates don't get loaded into the database in correct order. How can I fix this so it will wait until each iteration of loop is complete or something like that. Thanks
/* Inserts the latitude and longitude points from the latitudeAndLongitudePoints ArrayList
into the latitudeandlongitudepoints table in db*/
private void insertLatitudeAndLongitudePoints(){
//iterates though array of co-ordinates, and adds to database
for(int loop=0; loop<latitudeAndLongitudePoints.size();loop++) {
final int index = loop;
StringRequest stringRequest = new StringRequest(Request.Method.POST,
"http://rrush01.lampt.eeecs.qub.ac.uk/insertLatitudeAndLongitudePoints.php",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Error: " + error.getMessage(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("Latitude", String.valueOf(latitudeAndLongitudePoints.get(index).latitude));
params.put("Longitude", String.valueOf(latitudeAndLongitudePoints.get(index).longitude));
params.put("User", AccountInfo.accountEmail);
return params;
}
};
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(stringRequest);
}
}
Add dependency for Volley library in your build.gradle.
compile 'com.android.volley:volley:1.0.0'
Volley is a network library which makes fast and easier to make HTTP Request for android application. Using Volley library we don’t need to create AsyncTask to make multiple API calls in volley there is RequestQueue where we can enqueue each request. Here in this example, We used Google place autocomplete API. We are going to make synchronous HTTP Request using volley. To make synchronous HTTP request make a RequestFuture object. And make JsonObjectRequest pass this parameter RequestMethod, URL, pass object of type Json and pass RequestFuture instance.
RequestFuture<JSONObject> requestFuture=RequestFuture.newFuture();
final String mURL = "https://maps.googleapis.com/maps/api/place/
autocomplete/json?key="+KEY+"&input=" + input;
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST,
mURL,new JSONObject(),requestFuture,requestFuture);
MySingleton.getInstance(mContext).addToRequestQueue(request);
Add your request in RequestQueue. Now, whenever the user makes an HTTP request each request added to RequestQueue.To get response object from the requestFuture we call get() method. And we also set a timeout of let’s say 10 seconds so we don’t block the UI thread indefinitely in case our request times out.
try {
JSONObject object= requestFuture.get(10,TimeUnit.SECONDS);
} catch (InterruptedException e|ExecutionException e|TimeoutException e) {
e.printStackTrace();
}
Hope this helps you to understand how we can use volley used to make the synchronous HTTP request

Internal server error while connecting to Server in android using volley?

here my function code to post using volley
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_CHECK_IN,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
int status = jsonObject.getInt("status");
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError response) {
}
}) {
#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
public Map<String, String> getHeaders () {
Map<String, String> map = new HashMap<String, String>();
map.put("Content-Type", "application/json");
map.put("appid", appids);
map.put("timestamp", timestamps);
map.put("token", tokens);
map.put("signature", signatures);
return map;
}
};
}
I don't know what's wrong with my code, because of 2 days ago everything fine.
and when I tried to debug, error show like this
BasicNetwork.performRequest: Unexpected response code 500 for http://api/presence/check_in
can anyone help me, please? because I'm stuck and need help or reference to solve my error
thank you
HTTP code 500 is Internal Server Error. Read more here. It generally implies that server is not able to process the request and come up with a response. This means that the code for your application might be alright whereas the server might be encountering some issue processing the current request body. I see that you are sending String in your request body. One peculiar thing I noticed with sending String in request body is that, we also need to check if the String is null or not, better to to use .trim() method at the end of your string too, which will delete starting and trailing spaces. Something simple like not escaping single quotes ( ' ) for the field you are trying to insert onto the database at your server might cause this. So server side field validation and best practices like Prepared Statements is also crucial. If you are absolutely sure that your client end [android app] is alright, maybe the server is encountering some issue at the endpoint you are hitting.
Test your api with a rest client like POSTMAN or INSOMNIA to be absolutely sure that your server and api layer is working as intended. Good Luck

How to form an URL in Background thread before using it with an API?

I am working with an API for the first time.
My need is that I need to form an URL with certain parameters out of which one parameter cannot be formed in the Main UI thread and has to be formed in the Background thread.
I am planning to use to volley library to post the GET request.
I am using the Needle library which helps in running background tasks. This is What I have tried till now.
Needle.onBackgroundThread().execute(new UiRelatedTask<String>() {
#Override
protected String doWork() {
return url = GetUrl();
}
#Override
protected void thenDoUiRelatedWork(String result1) {
Log.e("JSON", url);
final JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener() {
#Override
public void onResponse(Object response) {
Log.e("JSON", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("JSON", error.toString());
}
});
RequestQueue queue = VolleyController.getInstance(Activity.this.getApplicationContext()).getRequestQueue();
queue.start();
queue.add(jsonObjectRequest);
}
});
But the Main problem is that After the GetUrl() method immediately the thenDoUiRelatedWork method is called hence the request is made using an Invalid URL as the URL will still be loading in the background and then when the loading of the URL is over I am logging the URL Which is right.
I cannot use an AysncTask as my app is already using three AsyncTaks and additionally two more could be activated by the user based on the feature he is using. And also the API request has to be done in various places (3-4 places) hence using an AsyncTask will not be suitable.
Can anyone help me to first form the URL fully in the Background and the use volley to post the GET request.

Android program logic flow of using callbacks

I am working on an Android App, in which I need to make a lot of http queries. Since Android has a constrain to prevent program making http request on UI thread, I have to use a lot of Async methods to get response from the server. I am not a guru of using callbacks, there's a code design problem I am facing now:
Basically, I have a activity to display. I want the app to make a HttpRequest to server when the activity is created, so I can prepare the content of the activity based on the query response.
Since I am using the Google Volley library to make http requests, my code design is:
// in the Activity
OnCreate(Bundle b){
String response = RequestManager.makeRequest(args);
// other works based on the response in this activity.
}
// RequestManager Class
public static String makeRequest(args){
String url = getUrl();
// response callback
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Don't know what to do here
}
};
// error callback
Response.ErrorListener errorListener = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// deal with errors
}
};
BuildRequestAndPushToQueue(url, responseListener, errorListener);
// No way to return the response!
}
I know my design is totally incorrect, because String response = RequestManager.makeRequest(args); is intent to wait for a blocking call, but the call is actually async.
My ultimate goal is to let the response String returned to some code in the activity, so it can use the activity context to do the rest works (like access to a imageview, etc). But I am not sure how to design the code flow to make this happen.

GET request using GWT to retrieve XML data?

Oh hello there, fellow SO members,
I have a web service that returns XML data using a simple get request that goes like this :
http://my-service:8082/qc/getData?paramX=0169&paramY=2
the service returns raw xml in the page according to the parameters' values.
I am trying to retrieve this data from a GET request in GWT using RequestBuilder, Request, etc.
However, the response gives me empty text, a Status code of ZERO (which doesn't mean anything and isn't supposed to happen), and so on.
Here's the simplified code that doesn't work.
public class SimpleXML implements EntryPoint {
public void onModuleLoad() {
this.doGet("http://my-service:8082/qc/getData", "0169", "2");
}
public void doGet(String serviceURL, String paramX, String paramY) {
final String getUrl = serviceURL + "?paramX=" + paramX + "&idTarification=" + paramY;
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, getUrl);
try {
Request response = builder.sendRequest(null, new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
response.getStatusCode(); // Gives me 0 (zero) :(
}
#Override
public void onError(Request request, Throwable exception) {
// ... doesn't matter for this example
}
});
} catch (RequestException e) {
// ... doesn't matter for this example
}
}
}
I don't get why this wouldn't work, since this is REALLY simple, I've seen tutorials and they all show me this way of doing things..
Thanks in advance
The reason is, that browsers do not allow cross-site requests with AJAX (see Same Origin Policy).
This means, that you can only call a service on the same server, same port (using the same protocol) as your HTML page. If you want to perform cross-site requests, you can use JSONP, as explained in http://code.google.com/webtoolkit/doc/latest/tutorial/Xsite.html.

Categories

Resources