JSON response from a remote server
{"status":"success",
"data":{"auth_token":"9389e656c90e11c451443657c8e",
"user":{"active_location":" Airport"}}}
I need to store the auth_token and pass to the remote server as the header,
tried addHeader("key1", "value1");
but still not working, need help
To send headers for belly request, you need to override getHeaders() method. Inside method create a map and put your key-value pairs and return the the map.
JsonObjectRequest request = new JsonObjectRequest(requestMethod, yourUrl, postData(if any), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//TODO parse your response
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//TODO handle error
}
}){
//Here is the place where you can add your headers
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("key1", "value1");
return params;
}
};
Also if you need to pass any request parameters you can do that in the same way by overriding getParams() method.
For more details check the volley tutorial
You can simply use Base64 to encode the token string and put it in SharedPrefs, then read and decode to send in a header.
Related
Peeps, I have some problem in understanding the working of volley library, so answer with proper material which can guide me to unobserved aspects of volley is what I am looking forward to.
How does my POST parameters are bind in network request. When I send params after overriding getParams() and by sending jsonObject directly in network request I don't receive any response but some server errors.
Since I am testing my backend on Postman, what postman actually does(my Observation) is it bind the params in url itself. When I copy paste the url in my android code it responds positively.
So, should I code to append my params to url or there's another way round?
I have alredy tried making changes to getHeaders() but it doesn't respond too!
You should use a JsonObjectRequest with a jsonObject containing all your params.
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "8327483274823");
JSONObject jsonObject = new JSONObject(params);
JsonObjectRequest req = new JsonObjectRequest(URL,jsonObject ,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
//Do stuff here
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Handle Errors here
}
});
I am trying to use volley to add a score to my database. I have tested my URL with a POST request using Postman, I have also manually typed the URL with parameters in the android app to the POST request, and that works. so I assume that my issue is in my android code? Or do I have to use the getParams to manually build the url string?
the error I'm getting from my backend:
Error: ER_BAD_FIELD_ERROR: Unknown column 'undefined' in 'field list'
which makes me think that my parameters aren't getting initialized prior to the StringRequest being called.
public void submitHighScore(){
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
Toast.makeText(context, response , Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error
Toast.makeText(context, "Error: unable to submit Score " + error , Toast.LENGTH_SHORT).show();
}
}
){#Override
protected Map<String, String> getParams() throws com.android.volley.AuthFailureError
{
Map<String, String> params = new HashMap<String, String>();
params.put("playerName", "Android test");
params.put("playerScore", "3000");
return params;
}
};
HighScoreSingleton.getInstance(context).addToRequestQueue(postRequest);
For those who may or may not believe me about my code on my server side.
app.post('/api/highScore', function(req,res){
var con = mysql.createConnection({
host: "xxxx",
user: "xxxx",
password: "xxxx",
database: "xxxx"
});
if(req.query!=null){ //
console.log(typeof req.query.playerName);
con.query(`INSERT INTO xxxx (playerScore, playerName) VALUES
(${req.query.playerScore}, "${req.query.playerName}" )`, // async, runs callback aka function
function(err,rows){
if(err) throw err;
res.setHeader('Content-Type', 'text/plain');
res.send('Updated High Score');
});
con.end();
}
});
Thank you in advance, It's very possible I'm overlooking something very simple, otherwise I will just modify my URL in my StringRequest as this seems a bit silly, given the getParams method.
I Hope this will work for you.
I think you need to add header
Override this method.
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = super.getHeaders();
if(params==null)params = new HashMap<>();
params.put("Content-Type","text/plain");
return params;
}
I'm trying to communicate between Android and a Flask server I've set up on AWS. I have some data I've put inside a JSONObject, and I'm sending that over a POST request to the server.
The Flask server receives this JSON, parses it, and even does the appropriate manipulations. However, when I send a Response back to Android, it doesn't seem to identify it at all.
I believe I'm going wrong in the Flask return part, but I don't know where exactly.
Here's the Flask return code:
parsed_results = parse_text(results)
#json_x = json.dumps({'id':str(status.inserted_id), 'Result':'OK', 'data': parsed_results})
return Response(json.dumps({'id': str(status.inserted_id), 'Result': 'OK', 'data': parsed_results, 'raw_data': results}), mimetype='application/json'), 200
if __name__ == "__main__":
app.run(host='0.0.0.0', debug=True)
Here's the Android Listener code:
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.POST,
URL,
data,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("JSON_TAG", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}
)
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
return super.getParams();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
//return super.getHeaders();
Map<String,String> headers = new HashMap<>();
headers.put("Content-Type","application/json");
return headers;
}
};
The Android application just stays idle. Where am I going wrong? Any help would be greatly appreciated. Thanks!
I solved the issue, guys. The problem was very apparent - a mismatched return statement from the server. By using jsonify, I was able to return the data to the server.
from flask import jsonify
results = parse_results(data)
return jsonify(results)
Worked like a charm!
So I'm running into a problem when calling rest-auth/user/.
I am able to login and obtain the key from said login, but from that I'm not sure how to use it in regards to rest-auth/user/. I've tried using it with GET in volley, as well as POSTing it in volley. But everytime I try to do so, I get a 403 back saying credentials were not provided. I've also tried saving the token to Android's SharedPreferences.
I'm not sure what could be wrong or how to fix this problem, so any help would be appreciated.
My code looks like this:
getUserQueue = Volley.newRequestQueue(this);
JSONObject jsObj = new JSONObject();
try {
jsObj.put("token", token);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, "http://hurst.pythonanywhere.com/supportal/rest-auth/user/", jsObj, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
result = response.getString("username");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
// add the request object to the queue to be executed
getUserQueue.add(jsObjRequest);
From comments it is clear that you are using different authentication schemes for rest, will explain these,
SessionAuthentication
For authenticating session authentication you need persistant cookie implementation in android volley, check here for this, where Set-Cookie header is parsed from server api response & send over next requests.
BasicAuthentication
In Basic authentication scheme, username & password are send over every request ( after login ?), with Authorization header value ( Base64 encoded).To check how to implement this check here
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
String creds = String.format("%s:%s","USERNAME","PASSWORD");
String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT);
params.put("Authorization", auth);
return params;
}
JSONWebTokenAuthentication
In JWT authentication scheme, after successful login you will get a JWT token, you need to send this token in every request that need user authorization, for this to work, set Authorization header value with JWT token_after_login;Only difference with Basic authentication is how header is send.
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
String auth = "JWT " + token // token you will get after successful login
params.put("Authorization", auth);
return params;
}
How do I send a DELETE Request using Volley (Android) to a REST Api with parameters like access_token and username. I have tried almost everything on Internet but still I am getting a 400 error Message.
I have tried sending the same DELETE request using PostMan and it works perfectly fine.
Here is the Error:
E/Volley﹕ [1112] BasicNetwork.performRequest: Unexpected response code 400 for http://myserverip/messages/2
and Here is the Java code that I am using:
String URI = "http://myserverip/messages/2";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.DELETE,URI,null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(contextm,response.toString(),Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
headers.put("access_token", "access_token");
headers.put("username", "username");
return headers;
}
};
MyApp.getInstance().addToRequestQueue(request);
Might not be really useful but here is the working DELETE request preview from PostMan
DELETE /messages/1 HTTP/1.1
Host: serveripaddress
Cache-Control:no-cache
Content-Type: application/x-www-form-urlencoded
access_token=SPAVYaJ7ea7LzdeQYrBTsIRssuGbVpJI8G9XSV0n&username=whit3hawks
You can easily achieve this if you put the following instead of null in ... new JsonObjectRequest(Request.Method.DELETE,URI,null,new Response.Listener<JSONObject>() { ...
final JSONObject object = new JSONObject();
try {
object.put("access_token", "SPAVYaJ7ea7LzdeQYrBTsIRssuGbVpJI8G9XSV0n");
object.put("username", "whit3hawks");
} catch (Exception e) {
e.printStackTrace();
}
So your Request should look like this:
... new JsonObjectRequest(Request.Method.DELETE,URI,object,new Response.Listener<JSONObject>() { ...
You posted a long time ago, but maybe someone else will need this some time.
I am successfully sending headers in volley while using DELETE with this code:
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
return headers;
just tried it and works like a charm.
EDIT:
if you're using a Mac, try checking with Charles what exactly it is you are sending,
on a PC you can try fiddler.
also, error 400 means 'Bad Input', so the server is either getting more info then it should, or less then he expects.
and keep in mind that DELETE in Volley acts as a GET, make sure you are sending an empty body with the request.
hope that helped somehow.. happy coding