Send ByteArray with Android volley - android

There is any way to send a byte array with Volley?
Now I'm using this:
post.setEntity(new ByteArrayEntity(rawPacket.toByteArray()));
try {
response = client.execute(post);
} catch (IOException e) {
e.printStackTrace();
}
There is something like this in Volley? There is a method to pass custom object to send with the POST/GET request?
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> params = new HashMap<>();
params.put("RawPacket", rawPacket.toByteArray().toString());
return params;
}
I need something like protected Map<String, ByteArray> getParams()

I find the solution overriding the function public byte[] getBody() to send custom data, I should read better the documentation!
StringRequest stringRequest = new StringRequest(Request.Method.POST, "https://www.example.com/",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
return new byte[] {1, 2, 3, 4, 5};
}

See code below:
public class JsonArrayRequest extends JsonRequest<JSONArray> {
/**
* Creates a new request.
* #param url URL to fetch the JSON from
* #param listener Listener to receive the JSON response
* #param errorListener Error listener, or null to ignore errors.
*/
public JsonArrayRequest(String url, Listener<JSONArray> listener, ErrorListener errorListener) {
super(Method.GET, url, null, listener, errorListener);
}
You have to create a subclass of JsonRequest and use that instead.
See related link:
Volley - Sending a POST request using JSONArrayRequest
Also might want to Base64 encode the bytes and add it to the JsonArray.

Related

GET Request parameters using Volley

I'm making an Android App that integrates with the Facebook API and uses a REST API, so I'm using Volley. However, I'm trying to issue a GET request for a JSON Array, and have to include the Facebook Authorization token in order to access the server. Most of the questions I've seen on this are relatively old, and it seems like Volley now provides support to pass in request params (from the volley github page):
/**
* Creates a new request.
* #param method the HTTP method to use
* #param url URL to fetch the JSON from
* #param jsonRequest A {#link JSONArray} to post with the request. Null is allowed and
* indicates no parameters will be posted along with request.
* #param listener Listener to receive the JSON response
* #param errorListener Error listener, or null to ignore errors.
*/
public JsonArrayRequest(int method, String url, JSONArray jsonRequest,
Listener<JSONArray> listener, ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
errorListener);
}
But when I make and issue a JsonArrayRequest, I get a com.android.volley.AuthFailureError. Here is my code, does anyone know what I'm doing wrong?
#Override
protected void onCreate(Bundle savedInstanceState) {
System.out.println("Yo im here");
JSONObject requestParams = new JSONObject();
JSONArray paramArray = new JSONArray();
try {
requestParams.put("Authorization", "JWT (Facebook auth token)");
paramArray.put(requestParams);
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println(paramArray.toString());
RequestQueue queue = Volley.newRequestQueue(this);
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET,
GET_MAP_MICS,
paramArray,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray micArray) {
try {
for (int i = 0; i < micArray.length(); i++) {
JSONObject jsonobject = micArray.getJSONObject(i);
int micId = jsonobject.getInt("micId");
String status = jsonobject.getString("status");
System.out.println("Good so far!");
double venLat = jsonobject.getDouble("venueLat");
double venLong = jsonobject.getDouble("venueLat");
System.out.println("got here, check it: " + venLat);
}
}catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError e) {
System.out.println(e);
}
});
GET method don't take parameters only POSTwill
in your case your passing Headers as body for GET method you have pass headers
JsonObjectRequest request = new JsonObjectRequest(url, (JSONObject) null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> map = new HashMap<>();
/*Add your headers here*/
return super.getHeaders();
}
};
final possibility there is two same class name will be there in your project for example any lib your using also using volley lib this happens once for me

Add Payload to Volley post request

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.

Android - Volley JSON request to remote server only works correctly once

I am developing an Android app where I need to fetch results from a MySQL database in a remote server. I have written some PHP scripts to query the database and output the results in JSON format.
The problem is that the request fetches expected results only for the first time. When I send the same request with different POST params, it returns the first result all over again. I modified the PHP script to attach the POST param in the JSON result and tried logging the POST param. It is also the same first param.
If I uninstall the app from the device and re-install, again it returns the correct JSON only for the first time.
NOTE: When i run the same code with the same PHP scripts and same database on localhost (WAMPP), everything works perfect.
I tried using the Google Chrome extension Postman to check the output from the remote server, it worked as expected. So, I can confirm that the problem is with my app/code.
Here's my CustomJSONObjectRequest class :
public class CustomJSONObjectRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomJSONObjectRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomJSONObjectRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
};
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(JSONObject response) {
listener.onResponse(response);
}
}
And this is how I am sending the request :
String item_name = getIntent().getExtras().getString("item_name");
String url = getString(R.string.remote_server)+"fetch-item-list.php";
CustomJSONObjectRequest jsObjRequest = new CustomJSONObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d("item name from intent extra", item_name); //intent extra
Log.d("response", response.toString()); //json response
Log.d("item name from response", response.getString("item_name")); //post parameter. This and the intent extra should be same
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("item_name", item_name);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> header = new HashMap<String, String>();
header.put("Content-Type", "application/json; charset=utf-8");
return header;
}
};
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsObjRequest);
This is the logcat :
D/item name from intent extra: apple
D/Response: {"data":[{"item_discount":"0.00","item_price":"50.00","unique_id":"181................
D/item name from response: orange
I think I found the solution
Looks like the JSON response was getting cached, so the response for the first request got cached and the next requests were never sent to the server. The cached JSON response was returned for every other requests.
All I had to do was disable caching.
I added the line jsObjRequest.setShouldCache(false); before adding it to the request queue.
jsObjRequest.setShouldCache(false);
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsObjRequest);
Thanks to this question.
But I still do not get it why it worked on localhost without this setting.

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";
}
};

Categories

Resources