I need to maintain a session for below REST API call from Android app. I'm able to call these API using volley, But the session is not being maintained.
I first call validateUser API to validate the user and store his email in session.
Then I need to call getDashboardDetails to fetch user details, But email in session object is null
// Spring REST code
#RequestMapping(value = "/validateUser", method = RequestMethod.POST)
#ResponseBody
public ResponseEntity<UserVO> validateUser(#RequestBody UserVO userVO, HttpSession session, HttpServletResponse response) {
HttpStatus httpStatus = HttpStatus.OK;
validatedUserVo = userService.getUserDetails(userVO);
session.setAttribute("email", validatedUserVo.getEmail());
return new ResponseEntity<UserVO>(validatedUserVo, httpStatus);
}
#RequestMapping(value = "/getDashboardDetails", method = RequestMethod.GET)
public ResponseEntity<List<DashBoardVO>> getDashboardDetails(HttpSession session) {
List<DashBoardVO> dashBoardVOList = null;
HttpStatus httpStatus = HttpStatus.OK;
String email = (String)session.getAttribute("email");
if(email!=null){
dashBoardVOList = dashboardService.getDashboardDetails(email);
}
else{
httpStatus = HttpStatus.BAD_REQUEST;
}
return new ResponseEntity<List<DashBoardVO>> (dashBoardVOList, httpStatus);
}
// validateUser call in LoginActivity
json.put("email",username1.getText().toString());
json.put("password",password1.getText().toString());
JsonObjectRequest login_data = new
JsonObjectRequest(Request.Method.POST, url, json,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
StringBuffer s = null;
tv.setText(response.toString());
edit.putBoolean("login_success",true);
edit.commit();
Intent i = new Intent(LoginActivity.this,DashboardActivity.class);
try {
i.putExtra("name",response.getString("name"));
i.putExtra("role",response.getString("role"));
} catch (JSONException e) {
e.printStackTrace();
}
startActivity(i);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
tv.setText(error.toString());
}
});
RequestQueue rq = Volley.newRequestQueue(this);
rq.add(login_data)
//sharedPreferences in LoginActivity
boolean b = sharedPreferences.getBoolean("login_success",false);
if(b){
Intent i = new
Intent(LoginActivity.this,DashboardActivity.class);
startActivity(i);
}
// getDashboardDetails call in DashboardActivity
JsonArrayRequest j1 = new JsonArrayRequest(Request.Method.GET, url,
null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
JSONObject temp = response.getJSONObject(1);
tv.setText(temp.getString("id"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
tv.setText(error.toString());
}
});
RequestQueue rq = Volley.newRequestQueue(this);
rq.add(j1);
How do I use/maintain session between different api calls? in android app
Related
I am using Volley to make Api call and set data to RecyclerView.I have my first Volley where I get Id field and I use this same Id to make another Api call. I used the response from both api call at same time and set the data to RecyclerView.But the response from second Api call is not set on Recyclerview at same time.Later I manually refresh tab and set data from Database its set.
This is my nested Volley Api call
private void getData() {
final JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, ApiUrls.FirstCall, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
if (response != null) {
for (int i = 0; i < response.length(); i++) {
JSONObject object = response.getJSONObject(i);
CurrentStatusEntry entry = new CurrentStatusEntry();
String Id= object.getString("id");
id_url = ApiUrls.Info+ Id + "/";
JsonObjectRequest foodie_request = new JsonObjectRequest(Request.Method.GET, id_url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String name=response.getString("name");
String address=response.getString("address");
entry.setName(name);
entry.setAddress(address);
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
})
AppController.getInstance().addToRequestQueue(foodie_request, foodie_data_req);
current.add(entry);
if (current.size() > 0) {
adapter = new QueueAdapter(current, getActivity().getApplicationContext());
recyclerView.setAdapter(adapter);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
})
AppController.getInstance().addToRequestQueue(request, restqueue_req);
}
The data from second api call is not set instantly. How to perform this ?
I am developing an app in which i find the origin and destination of a car and send it to a server.
I know how to use volley to send an string however i am finding it hard to send data in JSON format.
Part of the code is given below:
b
tnFindPath.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RequestQueue queue = Volley.newRequestQueue(MapsActivity.this);
String url = "http://192.168.43.162:8080/";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
//adding parameters to the request
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("origin", etOrigin.getText().toString());
params.put("destination", etDestination.getText().toString());
return params;
}
};
// Add the request to the RequestQueue.
queue.add(stringRequest);
try this
final String httpUrl = //your url
try {
JSONArray parameters = new JSONArray();
JSONObject jsonObject = new JSONObject();
jsonObject.put(Key,value);
jsonObject.put(Key,value);
parameters.put(jsonObject);
Log.i(TAG,parameters.toString());
JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.POST, httpUrl, parametersForPhp,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG,response.toString());
try {
//your code
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
RequestQueueSingleton.getInstance(getApplicationContext()).addToRequestQueue(arrayRequest);
}catch (Exception e){
e.printStackTrace();
}
}
I am trying to hit multiple request using Volley and i am getting response for all the request. my problem is how to identify the response is belong to which API.
mQueue = CustomVolleyRequest.getInstance(this.getApplicationContext())
.getRequestQueue();
final CustomJSONObjectrequest jsonRequest = new CustomJSONObjectrequest(Request.Method
.GET, url,
new JSONObject(), this, this); //
jsonRequest.setTag(REQUEST_TAG);
final CustomJSONObjectrequest jsonRequest2 = new CustomJSONObjectrequest(Request.Method
.GET, url2,
new JSONObject(), this, this);
jsonRequest2.setTag(REQUEST_TAG);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mQueue.add(jsonRequest);
mQueue.add(jsonRequest2); // Both the request will have different API request
}
});
}
#Override
public void onErrorResponse(VolleyError error) {
mTextView.setText(error.getMessage());
}
#Override
public void onResponse(Object response) {
// How to identify, which response is belong to which api request
mTextView.setText("Response is: " + response);
}
Create a Generic Volley class and a Interface, Use the interface to get success and failure responds.
Step 1 Create a separate Volley class
Step 2 Create a interface for accessing the response from volley class
Step 3 create new object for
the class and send required parameters
new PostVolleyJsonRequest(TestVolley.this, TestVolley.this(interfcae), "Submit", url, params);
Context of the class
Interface for sending Success and failure responds
Type of request to identify on success
url (mandatory)
Param (optional) for GET no need
Generic volley class
public class PostVolleyJsonRequest {
private String type;
private Activity act;
private VolleyJsonRespondsListener volleyJsonRespondsListener;
private String networkurl;
private JSONObject jsonObject = null;
private JSONObject params;
public PostVolleyJsonRequest(Activity act, VolleyJsonRespondsListener volleyJsonRespondsListener, String type, String netnetworkUrl,JSONObject params) {
this.act = act;
this.volleyJsonRespondsListener = volleyJsonRespondsListener;
this.type = type;
this.networkurl = netnetworkUrl;
this.params = params;
sendRequest();
}
private void sendRequest() {
Log.d("url", "url" + networkurl);
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,networkurl,params,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.e("response", "response " + response);
volleyJsonRespondsListener.onSuccessJson(response, type);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
NetworkResponse response = error.networkResponse;
Log.e("response", "response " + response);
if (response != null) {
int code = response.statusCode;
String errorMsg = new String(response.data);
Log.e("response", "response" + errorMsg);
try {
jsonObject = new JSONObject(errorMsg);
} catch (JSONException e) {
e.printStackTrace();
}
String msg = jsonObject.optString("message");
volleyJsonRespondsListener.onFailureJson(code, msg);
} else {
String errorMsg = error.getMessage();
volleyJsonRespondsListener.onFailureJson(0, errorMsg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
jsObjRequest.setRetryPolicy(new DefaultRetryPolicy(
600000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue requestqueue = Volley.newRequestQueue(act);
requestqueue.add(jsObjRequest);
}
}
Use the interface to get responds message
public interface VolleyJsonRespondsListener {
public void onSuccessJson(JSONObject result, String type);
public void onFailureJson(int responseCode, String responseMessage);
}
In your class where you want to include multiple request
public class TestVolley extends AppCompatActivity implements VolleyJsonRespondsListener{
//Your class code goes here
//network request
try {
//parameters
//Context,Interface,Type(to indentify your responds),URL,parameter for your request
//request 1
new PostVolleyJsonRequest(TestVolley.this, TestVolley.this, "Submit", url, params);
//request 2
new PostVolleyJsonRequest(TestVolley.this, TestVolley.this, "AccessData", url_2, params_2);
} catch (Exception e) {
e.printStackTrace()
}
//Methods from Interface
#Override
public void onSuccessJson(JSONObject result, String type) {
//Based on the Type you send get the responds and parse it
switch (type) {
case "Submit":
try {
parseSubmit(result);
} catch (Exception e) {
e.printStackTrace();
}
break;
case "AccessData":
try {
parseAccessData(result);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
You can do something like this for a single request. Same can be applied to the second request. This way you know which request is giving you the response.
final CustomJSONObjectrequest jsonRequest = new CustomJSONObjectrequest(Request.Method
.GET, url,
new JSONObject(), this, new Response.Listener<Object>() {
#Override
public void onResponse(Object response) {
// How to identify, which response is belong to which api request
mTextView.setText("Response is: " + response);
});
EDITED :
You can start with making an interface like :
public interface VolleyResponse {
void onResponse(JSONObject object, String tag);
void onError(VolleyError error, String tag);
}
Then you can make a custom handler for volley request like:
public class CustomJSONObjectRequest implements Response.Listener<JSONObject>, Response.ErrorListener {
private VolleyResponse volleyResponse;
private String tag;
private JsonObjectRequest jsonObjectRequest;
public CustomJSONObjectRequest(int method, String url, JSONObject jsonObject, String tag, VolleyResponse volleyResponse) {
this.volleyResponse = volleyResponse;
this.tag= tag;
jsonObjectRequest = new JsonObjectRequest(method, url, jsonObject, this, this);
}
#Override
public void onResponse(JSONObject response) {
volleyResponse.onResponse(response, tag);
}
#Override
public void onErrorResponse(VolleyError error) {
volleyResponse.onError(error, tag);
}
public JsonObjectRequest getJsonObjectRequest() {
return jsonObjectRequest;
}
}
And to call it in your class use it like:
CustomJSONObjectRequest request1 = new CustomJSONObjectRequest(Request.Method.GET, url,
new JSONObject(), "YOUR REQUEST TAG", this);
Make sure to let your class implement the VolleyResponse interface that will get you the response and your tag.
#Override
public void onResponse(JSONObject object, String tag) {
Log.i("Response :", object.toString() + " " + tag);
}
#Override
public void onError(VolleyError error, String tag) {
}
To add the request to the volley queue you can use:
mQueue.add(request1.getJsonObjectRequest());
PS : this code is not tested but it should work.
im pretty new to Android Studio and I'm trying to build a Get Request using Volley, the Server response is a JsonObject. I tested the code with breakpoints but I wonder why I don't jump into onResponse or why it won't work.
Here's my Code of the Get Method:
public Account GetJsonObject(String urlExtension, String name, Context context) {
String baseURL = "myurl.com/api";
baseURL += urlExtension + "/" + name;
// url will look like this: myurl.com/api/user/"username"
final Account user = new Account("","");
//Account(name, email)
RequestQueue requestQueue;
requestQueue = Volley.newRequestQueue(context);
JsonObjectRequest jsonObject = new JsonObjectRequest(Request.Method.GET, baseURL,null,
new Response.Listener<JSONObject>() {
// Takes the response from the JSON request
#Override
public void onResponse(JSONObject response) {
try {
JSONObject obj = response.getJSONObject("userObject");
String username = obj.getString("Username");
String email = obj.getString("Email");
user.setUsername(username);
user.setEmail(email);
}
catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(jsonObject);
return user;
}
As #GVillavani82 commented your onErrorResponse() method body is empty. Try to log the error like this
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("ERROR", "Error occurred ", error);
}
}
Make sure that you have the below permission set in AndroidManifest.xml file and the api URL is proper.
<uses-permission android:name="android.permission.INTERNET"/>
And JsonObjectRequest class returns Asynchronous network call class. Modify your code like below.
// remove Account return type and use void
public void GetJsonObject(String urlExtension, String name, Context context) {
....
.... // other stuffs
....
JsonObjectRequest jsonObject = new JsonObjectRequest(Request.Method.GET, baseURL,null,
new Response.Listener<JSONObject>() {
// Takes the response from the JSON request
#Override
public void onResponse(JSONObject response) {
processResponse(response); // call to method
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("ERROR", "Error occurred ", error);
}
});
requestQueue.add(jsonObject);
}
Now create another method like below
private void processResponse(JSONObject response) {
try {
final Account user = new Account("","");
JSONObject obj = response.getJSONObject("userObject");
String username = obj.getString("Username");
String email = obj.getString("Email");
user.setUsername(username);
user.setEmail(email);
} catch (JSONException e) {
e.printStackTrace();
}
}
In my app I have an Activity LoginUserActivity that contains a button perform a connection to a web-server using JSONObject request and Volley. If the login is successfull will be launched another activity, but if it isn't I need to re-enable the button.
LoginUserActivity
public void OnLoginUtente(View view) {
final String mail = etMail.getText().toString();
final String pw = etPassword.getText().toString();
bLogin.setEnabled(false);
DBConnection connection = new DBConnection(mail, pw, getApplicationContext());
connection.doLogin();
}
doLogin()
public void doLogin() {
JSONObject obj = new JSONObject();
try {
obj.put("type", type);
obj.put("email", email);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, URL, obj,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Toast.makeText(context, response.getString("Status"), Toast.LENGTH_SHORT).show();
if (response.getString("Esito").equals("true")) {
intent = new Intent(context, MainUtente.class);
context.startActivity(intent);
}else{
//I think I've to put something here
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
jsonObjectRequest.setShouldCache(false);
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.getCache().clear();
requestQueue.add(jsonObjectRequest);
}
I've tried different things, such as make doLogin() return a boolean and then re-enable the button from the activity or try to inflate the layout of the calling activity in the else, but neither of these worked. If possible I'd like to keep the doLogin() method void and without parameters.
LoginUserActivity
public void OnLoginUtente(View view) {
final String mail = etMail.getText().toString();
final String pw = etPassword.getText().toString();
DBConnection connection = new DBConnection(mail, pw, getApplicationContext());
connection.doLogin(this);
}
public void disableLoginButton()
{
bLogin.setEnabled(false);
}
doLogin
public void doLogin(final LoginActivity activity) {
JSONObject obj = new JSONObject();
try {
obj.put("type", type);
obj.put("email", email);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, URL, obj,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Toast.makeText(context, response.getString("Status"), Toast.LENGTH_SHORT).show();
if (response.getString("Esito").equals("true")) {
new Handler(Looper.getMainLooper()).post(new Runnable(){
public void run() {
activity.disableLoginButton();
}
);
activity.disableLoginButton();
intent = new Intent(context, MainUtente.class);
context.startActivity(intent);
}else{
//I think I've to put something here
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
jsonObjectRequest.setShouldCache(false);
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.getCache().clear();
requestQueue.add(jsonObjectRequest);
}
You may replace new Handler(Looper.getMainLooper()).post(runnable) with activity.runOnUiThread(runnable)