I have a fragment that sends a Get request to server multiple times but with different arguments expecting different results.
This function accepts arguments and sends request successfully but there is a problem:
First execution of this function returns null but second execution returns first execution's result! and the problem is in execution sequence:
I added some toast comments to clarify: "Toast A" is in get request function and "Toast B" is after the function call. I figured out that "Toast A" is being executed AFTER "Toast B".
As you know by now, I am new to Java and answering this question helps me understand it better. My real question is not about sending Get request. I just want to know How java handles function's execution sequence. Thanks for guiding me.
This is how I call request function:
Map<String, String> header = new HashMap<>();
header.put("user_id", "123");
String[] responseString = get_request(header);
//Toast B
Here is my request function:
public String[] get_request(final Map<String, String> header) {
final String[] responseString = new String[1];
StringRequest stringRequest = new StringRequest(Request.Method.POST, getString(R.string.server) + "query.php", new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
responseString[0] = response;
//Toast A
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError e) {
responseString[0] = "";
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
return header;
}
};
Volley.newRequestQueue(getActivity().getApplicationContext()).add(stringRequest);
return responseString;
}
Related
I am new to APIs and finally figured out how to successfully retrieve a request response from a website. The thing is I am completely lost on how I should handle the response. I don't know how to access certain values within the response
here is my API Volley code
RequestQueue requestQueue = Volley.newRequestQueue(this);
String uri = Uri.parse("https://chicken-coop.p.rapidapi.com/games/Fortnite?platform=pc")
.buildUpon()
.build().toString();
StringRequest stringRequest = new StringRequest(
Request.Method.GET, uri, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
displayResults.setText("Response: " + response.substring(0,500));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
displayResults.setText( "" + error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("X-RapidAPI-Key", "5cdb2bbe57mshd9242c8d3177cb3p16f2fbjsnd7c5829eb4ad");
params.put("X-RapidAPI-Host", "chicken-coop.p.rapidapi.com");
return params;
}
};
requestQueue.add(stringRequest);
Here is the response query that I received
"result":{10 items
"title":"Fortnite"
"releaseDate":"Jul 25, 2017"
"description":"Epic Games next project has you building forts and stopping a zombie invasion."
"genre":[...
]6 items
"image":"https://static.metacritic.com/images/products/games/5/c7eb46ceb7da9c72c5a95193e8621faf-98.jpg"
"score":81
"developer":"Epic Games"
"publisher":[...
]1 item
"rating":"T"
"alsoAvailableOn":[6 items
0:
"iPhone/iPad"
1:
"PlayStation 3"
2:
"PlayStation 4"
3:
"Switch"
4:
"Xbox 360"
5:
"Xbox One"
How would I go about finding an explicit value from the response query? I have been searching for how to do this online and there are so many different ways to go about and I have no clue what to do. For example, how would I be able to put the Release Date into its own text box? Most of the examples I see online use JsonObjects when I m using a string response
in your onResponse method you need to parse your result so you can extract any data you want
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("result");
// toaccess to your json data
String title = jsonArray.getString("title");
// your code
} catch (JSONException e) {
e.printStackTrace();
}
}
I am trying to make a web-service call using volley and printing the response in the logcat. But I don't know why I am not getting response. Not even any error message.
Below is my code. I know I am missing something. Please correct me.
private void syncData() {
mProgressDialog.showProgressDialog("Initializing Please Wait...");
RequestQueue requestQueue = Volley.newRequestQueue(SalesDashboard.this);
StringRequest stringRequest = new StringRequest(Request.Method.POST, SYNC_DATA_SALES, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
mProgressDialog.dismissProgressDialog();
Log.e("TAG", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mProgressDialog.dismissProgressDialog();
Log.e("TAG", error.toString());
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String , String> params = new HashMap<>();
String userrole = mSessionManagement.getLoggedInUser().get(SESSION_USER_ROLE);
params.put("branch", mSessionManagement.getSelectedBranch());
params.put("staff_id", mSessionManagement.getLoggedInUser().get(SESSION_EMP_ID));
params.put("user_role", mSessionManagement.getLoggedInUser().get(SESSION_USER_ROLE));
params.put("user_dept", mSessionManagement.getLoggedInUser().get(SESSION_DEPT_IDS));
params.put("principal", mSessionManagement.getLoggedInUser().get(SESSION_PRINC_IDS));
if (userrole.equals(ADMIN) || userrole.equals(COUNTRY_MANAGER)) {
params.put("user_div", mSessionManagement.getSelectedDivision());
} else {
params.put("user_div", mSessionManagement.getLoggedInUser().get(SESSION_DIV_IDS));
}
return super.getParams();
}
};
requestQueue.add(stringRequest);
}
I am not receiving any error message also or any kind of exception. I have checked the webservice by hitting it on browser the response is displayed correctly on the browser but not able to fetch it in android.
Why you call super.getParams() on return instead params? Maybe it turn wrong on your request. Then try as follow
#Override
protected Map<String, String> getParams() throws AuthFailureError {
...
return params;
}
Bonus: use getMessage instead do toString() your error object
Print the stringRequest and check the url and cross verify with ur url
Before that check have u added Internet permissions in manifest file.
I've got a problem with Volley request - I want to send GET (another similiar POST also) request with JSONObject param (user having password and login) to authorize user and send back full user data. Although I can see during debugging that mRequestBody is correct JSON but I cannot receive it by my controller -
private void processLogin() throws JSONException {
this.user.setLogin(this.loginText.getText().toString());
this.user.setPassword(this.passwordText.getText().toString());
final JSONObject jsonObject = new JSONObject(new Gson().toJson(this.user));
final JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, UrlHelper.loginUrl, jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
user = new Gson().fromJson(response.toString(), User.class);
if (user.getUserId().equals(getResources().getString(R.string.ERROR))) {
onLoginFailed();
} else {
onLoginSuccess(user);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
return headers;
}
};
VolleySingleton.getInstance(this).addToRequestQueue(request);
}
Controller method:
#RequestMapping(value = "/loginTest", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
public User someMethod(#RequestBody User user) throws SQLException {
return userService.authenticateUser(user.getLogin(), user.getPassword());
}
Without annotation #RequestBody I it process but User in param is empty, so I process User with null password and login. Recently I did it by StringRequest Please, help me. :)
As a part of the HTTP specs, GET requests have no body. You can create and send GET requests with a body though, but that's meaningless since the body has no semantic meaning in the GET method specification. I don't know too much about Spring, but my guess is that Spring is probably ignoring the body of the request because it's a GET method. You should send and receive the request as POST if your intention is to put something inside the body.
I was trying Post method with using Volley and I got: com.android.google.volley server error.
I tested my api in postman and it works.
Here is my code:
StringRequest request=new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("Response", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error :",error.getMessage());
}
}) {
#Override
public Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("name", film.toString());
params.put("email", spin.toString());
params.put("password", spin_iki.toString());
params.put("address", spin_uc.toString());
params.put("brand", name.toString());
return params;
}
};
RequestQueue queue= Volley.newRequestQueue(film.this);
queue.add(request);
}
});
Normally I use my api like http://myurl/api/values/Post?film=...&email=...
How can I fix this? Thank you.This my API's Post method code
[HttpPost]
public int Post_film(string name, string email, string password, string address, string brand)
{
using (var context = new Entities())
{
db_table nesne = new db_table();
nesne.name =name;
nesne.email = email;
nesne.password = password;
nesne.address = address;
nesne.brand = brand;
context.db_table.Add(nesne);
int i = context.SaveChanges();
return i;
}
}
this my Postman SS
enter image description here
OK, you're sending a POST request but still adding parameters via URL. If your server is taking these parameters from the URL, then your Volley request will never work because overriding getParams() only works for parameters inside the request body, not parameters attached to the URL. You should either change the way your server is taking the parameters or, in your Android code, generate a string URL with all the parameters attached to it like "http:://myUrl.com/?email=something&name=something". To me, the most logical option is to change your server side code, because it doesn't make too much sense to expect a POST request with parameters in the URL. Parameters in POST requests should be inside the request body,
I have created an activity in which i insert some records into a mysql database. I declared a global variable named lastInsertId. When i try to println the variable inside the onResponse method, works fine but when i try to println outside the method returns null. I need to use this variable also outside the method. What can be done?
Here is my code:
String insertUrl = "http://localhost/file.php";
String lastInsertId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
StringRequest request = new StringRequest(Request.Method.POST, insertUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
lastInsertId = response.toString();
System.out.println(lastInsertId); // returns the lastInsertId
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> parameters = new HashMap<String, String>();
// parameters
return parameters;
}
};
requestQueue.add(request);
System.out.println(lastInsertId); // get's null
}
Thanks!
They are different results because although you are firing your request to your local HTTP server, your last println fires BEFORE you set the lastInsertId.
You need to think multi-threaded. Your HTTP request is running in the background and the UI thread is continuing. So the order of execution is not in the order the code appears in your sample.
Request queue created
Request created
Request added to queue (presumably starting HTTP call also)
Prints out lastInsertId (null)
lastInsertId is set from your response
Prints out lastInsertId
user a setter method of your variable inside onResponse
This is happening because the lastInsertId is getting declared, but never initialized,
then the StringRequest request is using a callback through anonym interfaces to print the value, that is happening asynchronous way, but your code is going forward and tryinh to print the value before that happens.
you don net extra setters o getters, you need to validate / that the string is not empty, OR only print its value inside that callack.
I figure it out. I answered this question after about a year, beacuse i saw that this post had a few hundred visitor. Hope my answer will help other feature visitors to get data out from onResponse method. Here is the code:
String insertUrl = "http://localhost/file.php";
String lastInsertId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
StringRequest request = new StringRequest(Request.Method.POST, insertUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
lastInsertId = response.toString();
System.out.println(lastInsertId); // returns the lastInsertId
callback.onSuccess(lastInsertId);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> parameters = new HashMap<String, String>();
// parameters
return parameters;
}
};
requestQueue.add(request);
}
public interface VolleyCallback{
void onSuccess(ArrayList<Data> dataArrayList);
}
And this is the code we need inside the Activity.
public void onResume(){
super.onResume();
getString(new VolleyCallback(){
#Override
public void onSuccess(String result){
System.out.println(result); // returns the value of lastInsertId
}
});
}