Add Payload to Volley post request - android

I'm using Volley as my http client library.
i need to send payload raw data as part of the request with Volley?
there are posts like: How to send Request payload to REST API in java?
but how this can be achieved using Volley?

need to use StringRequest as djodjo mentioned.
also getBody method need to be override - taken from here Android Volley POST string in body
#Override
public byte[] getBody() throws AuthFailureError {
String httpPostBody="your body as string";
// usually you'd have a field with some values you'd want to escape, you need to do it yourself if overriding getBody. here's how you do it
try {
httpPostBody=httpPostBody+"&randomFieldFilledWithAwkwardCharacters="+ URLEncoder.encode("{{%stuffToBe Escaped/","UTF-8");
} catch (UnsupportedEncodingException exception) {
Log.e("ERROR", "exception", exception);
// return null and don't pass any POST string if you encounter encoding error
return null;
}
return httpPostBody.getBytes();
}

example:
final TextView mTextView = (TextView) findViewById(R.id.text);
...
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";
// 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) {
// Display the first 500 characters of the response string.
mTextView.setText("Response is: "+ response.substring(0,500));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mTextView.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
check the source and more info here
**UPDATE: ** If you need to add params you can simply override getParams()
Example:
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "val1");
params.put("randomFieldFilledWithAwkwardCharacters","{{%stuffToBe Escaped/");
return params;
}
You don't need to override getBody yourself neither encode special chars as Volley is doing this for you.

Related

How to access a password protected URL in android using volley library

I am trying to do the following task:
I am planning to use JsonObjectRequest (Volley Library) in my code and extract the credentials but I am not able to understand where would the Username and Password be required in the request. This is a code snippet. If anyone can tell where I need to authenticate the Username and Password in this code snippet to fetch the JSON Object, it would be very helpful.
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
VolleyLog.wtf(response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.wtf(error.getMessage(), "utf-8");
}
});
queue.add(jsonObjectRequest)
This is how you can use POST Method in volley:
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(final String response) {
try {
JSONObject object = new JSONObject(response);
// here is your json object
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// volley errors
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("username", username);
params.put("password", password);
return params;
}
};
queue.add(stringRequest);
Create a jsonObject with username and password then pass this object to the JsonObjectRequest
Your code will be like this :
JSONObject body= new JSONObject();
body.put("username", "user");
body.put("password", "userPassword");
JsonObjectRequest jsonObjectRequest= new JsonObjectRequest(Request.Method.POST, url,
body, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
VolleyLog.wtf(response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.wtf(error.getMessage(), "utf-8");
}
});
queue.add(jsonObjectRequest)
You need to understand what is form-data and how it is used:
Definition and Usage
The method attribute specifies how to send form-data (the form-data is sent to the page specified in the action attribute).
The form-data can be sent as URL variables (with method="get") or as HTTP post transaction (with method="post").
Notes on GET:
Appends form-data into the URL in name/value pairs
The length of a URL is limited (about 3000 characters)
Never use GET to send sensitive data! (will be visible in the URL)
Useful for form submissions where a user wants to bookmark the result
GET is better for non-secure data, like query strings in Google
Notes on POST:
Appends form-data inside the body of the HTTP request (data is not shown in URL)
Has no size limitations
To pass username and password arguments as form-data you can create StringRequest and override it's getParams method to return a map of data.
StringRequest request = new StringRequest(
Request.Method.POST,
requestUrl,
onResultListener,
onErrorListener) {
#Override
protected Map<String, String> getParams() {
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("username", username)
hashMap.put("password", password)
return hashMap;
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
// You can parse response here and throw exceptions when required.
return super.parseNetworkResponse(response);
}
};
queue.add(request)

Android Volley request failing while making a call to wit.ai API

I'm trying to use the speech recognition REST API service from wit.ai
I have used Volley to send a POST request to the URL
https://api.wit.ai/speech
This is what I have currently done:
void makeApiCall(){
StringRequest request = new StringRequest(Request.Method.POST, "https://api.wit.ai/speech", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("wit_response",response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("wit_response",error.toString());
}
}){
#Override
protected Map<String,String> getParams() throws AuthFailureError{
Map<String,String> params = new HashMap<>();
params.put("Authorization","Bearer XXXXXX"); //hidden my token
params.put("Content-Type","audio/mpeg3");
return params;
}
#Override
public byte[] getBody() throws AuthFailureError {
return sendToByte();
}
};
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.add(request);
}
I am receiving an error of com.android.volley.ClientError on the wit_response log key inside onErrorResponse() method
I have not missed the content type and authorization header, and my sendToByte function is succesfully returning an mp3 file converted to byte array.
What is the issue?
I had to use this link https://gist.github.com/anggadarkprince/a7c536da091f4b26bb4abf2f92926594
And use MultiPartRequest class as described in this to upload my file.
Please comment here if you need any assistance (for all future folks)

How to use Volley to POST a string in the body and to save the binary response to a file

I am currently using OkHttp, but I'd like to switch to Volley.
Maybe it is the late hour, but I can't seem to figure out how to send a POST request with just text in the body (in my app, the body is encrypted as a whole and then decrypted on the server side, and then split into params).
Also, my response should be a binary (not an image) that I'd like to save to a file.
I'm beginning to think that Volley isn't my best solution.
Help would be much appreciated.
Use getParams to add body in POSt, like here
url = "http://google.com";
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error response
}
}
) {
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "aaa");
params.put("param2", "bbb");
return params;
}
};
queue.add(postRequest);
Volley is not designed for sending/receiving big data and multipart request. Best would be to have data in response base64 encoded.
Volley offers a method getBody() which you can use to put any data into the HTTP request body:
#Override
public byte[] getBody() throws AuthFailureError {
byte[] body = new byte[0];
try {
body = mContent.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unable to gets bytes from content", e.fillInStackTrace());
}
return body;
}

StringRequest with JSON body

I'm trying to send a request using Volley but I can't figure how to make it work.
I need to send a POST request with JSON encoded data as the body, but after hours of trying different things I still can't make it work.
This is my current code for the request:
User user = User.getUser(context);
String account = user.getUserAccount();
String degreeCode = user.getDegreeCode();
final JSONObject body = new JSONObject();
try {
body.put(NEWS_KEY, 0);
body.put(NEWS_DEGREE, degreeCode);
body.put(NEWS_COORDINATION, 0);
body.put(NEWS_DIVISION, 0);
body.put(NEWS_ACCOUNT, account);
} catch (JSONException e) {
e.printStackTrace();
}
StringRequest request = new StringRequest(Request.Method.POST, GET_NEWS, new Response.Listener<JSONObject>() {
#Override
public void onResponse(String response) {
Log.i(TAG, response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + getMessage(error, context));
Toast.makeText(context, getMessage(error, context), Toast.LENGTH_SHORT).show();
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
return body.toString().getBytes();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type","application/json");
return headers;
}
};
queue.add(request);
But this code always returns "Bad request error"
Some things I've tried:
Override getParams() method instead of getBody(). (Didn't work)
Send a JSONObjectRequest with the body on the constructor. This one worked, but because my web service returns a String value I always get a ParseError. That's why I'm using StringRequest.
Any help is very much appreciated.
As already mentioned on njzk2's comment, the easiest way is to override getBodyContentType() instead. Overriding getHeaders() could probably work too, but you need to put all necessary headers, not only Content-Type, since you basically override the headers that the original method set.
Your code should look like this:
StringRequest request = new StringRequest(...) {
#Override
public byte[] getBody() throws AuthFailureError {
return body.toString().getBytes();
}
#Override
public String getBodyContentType() {
return "application/json";
}
};

Android Volley POST string in body

I'm trying to use Volley library to communicate with my RESTful API.
I have to POST string in the body, when I'm asking for the bearer Token. String should look like this:
grant_type=password&username=Alice&password=password123
And header:
Content-Type: application/x-www-form-urlencoded
More info about WebApi Individual Accounts:
http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
Unfortunately I can't figure out how can I solve it..
I'm trying something like this:
StringRequest req = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.v("Response:%n %s", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("grant_type", "password");
params.put("username", "User0");
params.put("password", "Password0");
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/x-www-form-urlencoded");
return headers;
}
};
I'm getting 400 Bad Request all the time.
I think that I'm actually sending request like this:
grant_type:password, username:User0, password:Password0
instead of:
grant_type=password&username=Alice&password=password123
I would be very grateful if anyone has any ideas or an advice..
To send a normal POST request (no JSON) with parameters like username and password, you'd usually override getParams() and pass a Map of parameters:
public void HttpPOSTRequestWithParameters() {
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://www.somewebsite.com/login.asp";
StringRequest postRequest = 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) {
Log.d("ERROR","error => "+error.toString());
}
}
) {
// this is the relevant method
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("grant_type", "password");
// volley will escape this for you
params.put("randomFieldFilledWithAwkwardCharacters", "{{%stuffToBe Escaped/");
params.put("username", "Alice");
params.put("password", "password123");
return params;
}
};
queue.add(postRequest);
}
And to send an arbitary string as POST body data in a Volley StringRequest, you override getBody()
public void HttpPOSTRequestWithArbitaryStringBody() {
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://www.somewebsite.com/login.asp";
StringRequest postRequest = 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) {
Log.d("ERROR","error => "+error.toString());
}
}
) {
// this is the relevant method
#Override
public byte[] getBody() throws AuthFailureError {
String httpPostBody="grant_type=password&username=Alice&password=password123";
// usually you'd have a field with some values you'd want to escape, you need to do it yourself if overriding getBody. here's how you do it
try {
httpPostBody=httpPostBody+"&randomFieldFilledWithAwkwardCharacters="+URLEncoder.encode("{{%stuffToBe Escaped/","UTF-8");
} catch (UnsupportedEncodingException exception) {
Log.e("ERROR", "exception", exception);
// return null and don't pass any POST string if you encounter encoding error
return null;
}
return httpPostBody.getBytes();
}
};
queue.add(postRequest);
}
As an aside, Volley documentation is non-existent and quality of StackOverflow answers is pretty bad. Can't believe an answer with an example like this wasn't here already.
First thing, I advise you to see exactly what you're sending by either printing to the log or using a network sniffer like wireshark or fiddler.
How about trying to put the params in the body? If you still want a StringRequest you'll need to extend it and override the getBody() method (similarly to JsonObjectRequest)
I know this is old, but I ran into this same problem and there is a much cleaner solution imo found here: How to send a POST request using volley with string body?

Categories

Resources