Hi there I am struggling to understand how exactly Volley request works. I have done similar things in NodeJs and the process seemed more intuitive.
String url = "http://my-json-feed";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//All I want is to use the response outside this scope
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
}
});
MySingleton.getInstance(this).addToRequestQueue(jsonObjectRequest);
//Example: How can I access the response here or in any other class?
In NodeJS this same process looks similar to this (with the help of node-fetch)
const response = await fetch(url);
const json = await response.json();
console.log(json);
And I can basically access json from anywhere in the same file or I can return it from the current function and use it anywhere where I call that function. I want to ask how can I do something similar in Java?
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
I am an android beginner learner .I want to know why should we use RequestQueue in our codes and pass JsonObjectRequest to RequestQueue as an argument .
enter image description here
The Volley uses two classes, RequestQueue and Request
RequestQueue is where all the requests are queued up that has to be executed,
it also manages the worker threads
and maintain network call in the background
also it handles reading from and writing to the cache
and also parsing the response and delivering the parsed response to mainthread.
Request is where network request is constructed.The request object has 3 major request:
JSON requests
JsonObjectRequest — A request for retrieving a JSONObject response body at a given URL
.
JsonArrayRequest — For retrieving JSON Array from the server.
Request takes 3 parameters that are passed to the constructor.
Request Method Type(GET,POST,PUT...).
Resource URL of the required object.
ResponseListener whose callback method contains the response.
ErrorListener whose callback method has an error has been occurred with request (provided error code and optional user-readable).
The snippet for the implementation of both JsonObjectRequest and JsonArrayRequest is as below:
String mJSONURLString= "json_url";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, mJSONURLString, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//add JsonObjectRequest request to queue
requestQueue.add(jsonObjectRequest);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, url, null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//add JsonArrayRequest to queue
requestQueue.add(jsonArrayRequest);
StringRequest — To retrieve response body as String from the server.
Method Type(GET,POST,...).
The Resource URL.
The Event Listeners.
Code snippet as below:
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Do something with the response
}
},
ImageRequest-To receive an image from the server,the network call has the similar structure as other network requests.
Code snippet as below:
String mImageURLString= "";
ImageRequest imageRequest = new ImageRequest(mImageURLString= , new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap response) {
// Assign the response to an ImageView
ImageView imageView = (ImageView) findViewById(R.id.imageView);
imageView.setImageBitmap(response);
}
}, 0,0, null);//Image width,Image height
//add request to queue
requestQueue.add(imageRequest);
When you're using Volley, RequestQueue will queue your requests on worker thread and then delivers the response to main thread. The reason why you need it is that you are not allowed to perform network operations on the main thread if your application targeting the Honeycomb SDK or higher. Thus you will not get NetworkOnMainThreadException.
This is more of a style thing, and a self-study thing, but In the volley code are listeners, and all the code I find online involve just nesting a override method inside the constructor. Not necessarily something I'm used to from a C# background. Actually not too great at lambda, anonymous methods neither.
I have no idea where to start, because it doesn't seem intuitive to me right now. But I'd like to separate out nested methods to their own respective methods. Or maybe even just the overridden methods if that is the only part that is needed.
final EditText textView = (EditText) findViewById(R.id.editText);
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://myURL";
JSONObject postparams = new JSONObject();
postparams.put("city", "london");
postparams.put("name", "bob");
// Request a string response from the provided URL.
JsonObjectRequest postRequest = new JsonObjectRequest(Request.Method.POST, url, postparams,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
textView.setText("Success: "+ response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
textView.setText(String.valueOf(error.networkResponse.statusCode));
}
}
);
// Add the request to the RequestQueue.
queue.add(postRequest);
What I would like is to name a method in the 2 Response arguments within the same class or maybe this itself to do the override. Is it possible? Something like.
...
JsonObjectRequest postRequest = new JsonObjectRequest(Request.Method.POST, url, postparams, myResponseListener(JSONObject response), myErrorResponseListener(VolleyError error));
// Add the request to the RequestQueue.
queue.add(postRequest);
}
public void myResponseListener(JSONObject response){
textView.setText("Success: "+ response.toString());
}
public void myErrorResponseListener(VolleyError error){
textView.setText(String.valueOf(error.networkResponse.statusCode));
}
Is there a simple way to something like this?
Edit: Trying linucksrox answer, to my surprise, the following actually stands alone as its own method... without a public(access modifier) or void(return type)??
Response.Listener<JSONObject> myListener(JSONObject response)
{
return new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
textView.setText("Success: "+ response.toString());
}
};
}
But when I try to plug in myListener as the 4th argument, it complains about the arguments.
myListener() no work,
myListener(JSONOBject response) no work
The same is for the error section argument.
You should be able to do something like this:
Response.Listener<JSONObject> myListener = new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
textView.setText("Success: "+ response.toString());
}
};
Response.ErrorListener myErrorListener = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
textView.setText(String.valueOf(error.networkResponse.statusCode));
}
};
// Request a string response from the provided URL.
JsonObjectRequest postRequest = new JsonObjectRequest(Request.Method.POST, url, postparams,
myListener, myErrorListener);
i am trying to send json using postman to Lavavel but i facing this error.
enter image description here
this is my json code:
{
"email":"test#test.com",
"password":"testtest"
}
and this is Laravel codes :
Route::get('/r','test#store');
and
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use Log;
class test extends Controller
{
public function store(Request $request)
{
$email = $request->input('email');
$password = $request->input('password');
Log::info('test');
Log::info($email);
Log::info($password);
DB::table('login')->insert([
['email' => $email],
['password' => $password]
]);
}
}
also i trying using android for send data using volley and so checked Laravel logs :
Column 'email' cannot be null (this is Laravel logs)
and on android Logs:
E/Volley: [299] BasicNetwork.performRequest: Unexpected response code 500 for http://192.168.1.4:8000/r
D/error: com.android.volley.ServerErro
my android code is :
public class ApiService {
private final Context context;
public ApiService(Context context){
this.context=context;
}
public void loginUser(String email, String password, final OnLoginResponse onLoginResponse){
JSONObject requestJsonObject=new JSONObject();
try {
requestJsonObject.put("email",email);
requestJsonObject.put("password",password);
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, "http://192.168.1.4:8000/r",requestJsonObject , new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("response",response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("error",error.toString());
}
}) {
#Override
public Map getHeaders() throws AuthFailureError {
HashMap headers = new HashMap();
headers.put("Content-Type", "application/json");
return headers;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(18000,DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(context).add(request);
} catch (JSONException e) {
Log.e(TAG, "loginUser: "+e.toString());
}
}
public interface OnLoginResponse{
void onResponse(boolean success);
}
}
I hope this helps people trying to search on how to send JSON data to laravel not only specific to android applications but to all. The goal of this solution is to identify whether you can send a JSON data to laravel or not.
First of all you have to download postman from https://www.getpostman.com/ to test if your API is really working or not.
Create a post request using postman. Be sure that you follow the example data below
Be sure that you set your Routes that would associate to the controller
This is the controller part that will show the JSON data you sent if it was successfully accepted or not.
And also, if ever you are trying to send POST data to laravel, by default they provided a CSRF Token which is applicable for the forms if you are going to use the MVC of laravel. For the meantime, we are going to take this down and comment it out. Just go to app/http/kernel.php
and now you'll get the following result from the code earlier
$json = json_decode($request['json']);
echo $json->{'email'};
echo "\n";
echo $json->{'password'};
We tested that we were able to send data to laravel. I hope this truly helps.
Wen you want to send data, you will want to use POST or PUT method on your postman, specially if you are sending a body, that means that you are sending data. Get method is used to retrieve data from a service.
Take a look into CRUD functions for more information.
Your postman should look something like this
Last in your android code try to change this line
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, "http://192.168.1.4:8000/r",requestJsonObject , new Response.Listener<JSONObject>() {
to use Request.Method.POST
Below is my class for handling http requests. I have tried the Volley Request in a new Android Project with no other code and the request is handled properly and I receive the result I expected. But for some reason when I use this code in my working project as a class, it doesn't return any response.
The way I call the request is:
HttpRequest request = new HttpRequest();
String url = "some-url";
String urlReturn = request.getFromURL(url, <ACTIVITY>.this);
where <ACTIVITY> is the activity I am calling the request from and "some-url" is a url that returns a string of data.
public class HttpRequest {
String response_test = "";
public String getFromURL (String url, Context context) {
RequestQueue requestQueue = Volley.newRequestQueue(context);
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("response1", response);
response_test = "1";
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Log.d("log2=", error.toString());
//requestQueue.stop();
}
});
// Add the request to the RequestQueue.
requestQueue.add(stringRequest);
requestQueue.start();
return response_test;
}
response_test never changes, so onResponse is never called. I thought there may be a timing issue, but when I add loop for it to wait until response_test is changed, it waits forever. Any idea what may be the issue? Anything I may have overlooked in how I'm calling this class?
Any help appreciated.
Volley is async library. It does work on another thread and when the call is ready it executes the code in onResponse. In the example you are returning imideately. Check your logcat for the messages they should be there
I am making JsonObjectRequest with Put method but it is not working and getting "{"detail":"Method \"GET\" not allowed."}" error message.
It is working fine on Postman. See attached screenshots for more information.
I didn't modify JsonObjectRequest. I copy this code from google sample code from here "http://developer.android.com/training/volley/request.html".
I don't think this could be a bug in Volley. Please go through my code and let me know what I am doing wrong.
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.PUT, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
hideDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
hideDialog();
}
})
{
#Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put("Authorization", "Token " + dm.readString("auth_token"));
return headers;
}
};
AppController.getInstance().addToRequestQueue(jsObjRequest);
Edit: I know in the screenshot it shows 400 bad request. It is because i need to pass 2 params ie {"dg_id":"80","delivery_ids":["90936"]}. With this params also i am getting the same error in Volley.
Sample auth_token Value: MTIzNDU2NzIzNDM6ZGVsaXZlcnlndXk=
Sample Body value: {"dg_id":"80","delivery_ids":["90936"]}
Add "/" at end of DELETE, PUT interface url,do check out the following snippet.
If a client issues a GET request to "/testdir/" (i.e., at the
directory).......It is interesting to take note that if a client issue
a GET request to "/testdir" (without specifying the directory path
"/"), the server returns a "301 Move Permanently" with a new
"Location" of "/testdir/", as follows.