Android Kotlin - Volley set POST Parameters in JsonArrayRequest - android

This is the code:
val requestQueue: RequestQueue = Volley.newRequestQueue(this#MainActivity)
val jsonArrayRequest = JsonArrayRequest(
Request.Method.POST,
"$domain/do_getmemes.php",
null,
Response.Listener { response ->
},
Response.ErrorListener { // Do something when error occurred
}
)
requestQueue.add(jsonArrayRequest)
and I just want to add some Parameters!
I've seen this JAVA example: https://gist.github.com/mstfldmr/f6594b2337e3633673e5
but I don't know what/where/how to add the parameters from this abomination of example.
I tried to add this part right after JsonArrayRequest():
{
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("user","YOUR USERNAME");
params.put("pass","YOUR PASSWORD");
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("Content-Type","application/x-www-form-urlencoded");
return params;
}
}
but it doesn't get converted to Kotlin.
I need to send some Ints and Strings

add object so you can override functions
val jsonArrayRequest = object : JsonArrayRequest(
Request.Method.POST,
"$domain/do_getmemes.php",
null,
Response.Listener { response ->
},
Response.ErrorListener { // Do something when error occurred
}
) {
override fun getBody(): ByteArray {
val parameters = HashMap<String, String>()
parameters["key"] = "value"
return JSONObject(parameters.toString()).toString().toByteArray()
}
}

Related

put parameter in request volley android with Kotlin

I need make request with Volley and kotlin my cod is
val stringReq = StringRequest(
Request.Method.GET, url,
Response.Listener<String> { response ->
var strResp = response.toString()
val jsonObj: JSONObject = JSONObject(strResp)
val jsonArray: JSONArray = jsonObj.getJSONArray("curso")
for (i in 0 until jsonArray.length()) {
var jsonInner: JSONObject = jsonArray.getJSONObject(i)
listGeral.add(jsonInner.get("interpret").toString());
listGeral2.add(jsonInner.get("titel").toString());
listGeral3.add(jsonInner.get("id").toString());
}
},
Response.ErrorListener {
})
queue.add(stringReq)
Now I need send 3 parameters for php. How do I put instruction for send parameter?
you can write the below code after Response.ErrorListener
val sr: StringRequest = object : StringRequest(Method.POST, "url",
Response.Listener { response ->
//your response
},
Response.ErrorListener { error ->
//your error
}) {
override fun getParams(): Map<String, String> {
val params: MutableMap<String, String> = HashMap()
params["user"] = "YOUR USERNAME"
params["pass"] = "YOUR PASSWORD"
return params
}
#Throws(AuthFailureError::class)
override fun getHeaders(): Map<String, String> {
val params: MutableMap<String, String> = HashMap()
params["Content-Type"] = "application/x-www-form-urlencoded"
return params
}
}
queue.add(sr)

Set post params with volley

I am trying to send a POST request with volley but I am not sure how to set the params. I tried this code
Map<String,String> map = new HashMap<String,String>();
map.put("test", "test");
JsonArrayRequest request = new JsonArrayRequest(Request.Method.POST, url, String.valueOf(new JSONArray(map)), this, this);
The app crashes when this code is executed with the error
Activity com.example.test.MainActivity has leaked ServiceConnection
In order to add POST parameters to your request you need to override the getParams() and 2 other methods of Request class:
public class MapJARequest extends Request<JSONArray> {
private final Map<String, String> params;
private Response.Listener<JSONArray> listener;
public MapJARequest( int method, String url, Map<String,String> params, Response.Listener<JSONArray> listener, Response.ErrorListener errorListener ) {
super( method, url, errorListener );
this.params = params;
this.listener = listener;
}
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
#Override
protected Response<JSONArray> parseNetworkResponse( NetworkResponse response ) {
try{
String jsonString = new String( response.data, HttpHeaderParser.parseCharset( response.headers ) );
return Response.success( new JSONArray( jsonString ), HttpHeaderParser.parseCacheHeaders( response ) );
}catch( Exception je ){
return Response.error( new ParseError( je ) );
}
}
#Override
protected void deliverResponse( JSONArray response ) {
listener.onResponse( response );
}
}
Be aware that you can not inherit from JsonArrayRequest straight away unfortunately.
you are down casting jsonArray to a string try not doing it.
This should help you,
JsonArrayRequest request = new JsonArrayRequest(Request.Method.POST, url, new JSONArray(map), this, this);
Let me know if u are still facing this issue.

Pass Parameter with Volley POST

I was able to call an HTTP endpoint using Postman and these parameters:
{
"name":"Val",
"subject":"Test"
}
However I am unable to do the same with Volley through Android: Here is trying to use JSONRequest:
HashMap<String, String> params2 = new HashMap<String, String>();
params.put("name", "Val");
params.put("subject", "Test Subject");
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.POST, Constants.CLOUD_URL, new JSONObject(params2), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
mView.showMessage("Response: " + response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
mView.showMessage(error.getMessage());
}
});
// Access the RequestQueue through your singleton class.
VolleySingleton.getInstance(mContext).addToRequestQueue(jsObjRequest);
And here is trying StringRequest
private void postMessage(Context context, final String name, final String subject ){
RequestQueue queue = Volley.newRequestQueue(context);
StringRequest sr = new StringRequest(Request.Method.POST, Constants.CLOUD_URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
mView.showMessage(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("name", name);
params.put("subject", subject);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("Content-Type","application/x-www-form-urlencoded");
return params;
}
};
queue.add(sr);
}
When I use JSONRequest, the call POSTs but no parameter is passed and when I use StringRequest I get the error below? How can I pass JSON data to Volley call?
E/Volley: [13053] BasicNetwork.performRequest: Unexpected response code 400 for
Here is the server code that handles the request
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
var helloRequest = await req.Content.ReadAsAsync<HelloRequest>();
var name = helloRequest?.Name ?? "world";
var responseMessage = $"Hello {personToGreet}!";
log.Info($"Message: {responseMessage}");
return req.CreateResponse(HttpStatusCode.OK, $"All went well.");
}
public class HelloRequest
{
public string Name { get; set; }
public string Subject { get; set; }
}
The server code is expecting a JSON object is returning string or rather Json string.
JsonObjectRequest
JSONRequest sends a JSON object in the request body and expects a JSON object in the response. Since the server returns a string it ends up throwing ParseError
StringRequest
StringRequest sends a request with body type x-www-form-urlencoded but since the server is expecting a JSON object. You end up getting 400 Bad Request
The Solution
The Solution is to change the content-type in the string request to JSON and also pass a JSON object in the body. Since it already expects a string you response you are good there. Code for that should be as follows.
StringRequest sr = new StringRequest(Request.Method.POST, Constants.CLOUD_URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
mView.showMessage(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mView.showMessage(error.getMessage());
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
HashMap<String, String> params2 = new HashMap<String, String>();
params2.put("name", "Val");
params2.put("subject", "Test Subject");
return new JSONObject(params2).toString().getBytes();
}
#Override
public String getBodyContentType() {
return "application/json";
}
};
Also there is a bug here in the server code
var responseMessage = $"Hello {personToGreet}!";
Should be
var responseMessage = $"Hello {name}!";
Add the content type in the header
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
return headers;
}
You are using params.put instead of params2.put in your hash map while passing parameters.
because your object name is params2

Android volley, how to pass post parameters dynamically

I'm new to google's Volley network library (and also to Android !), and I'm trying to pass POST arguments in a dynamic way !
For now I am overiding the : getParams() method :
And returning the params in an hard coded manner.
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("login", "my_login");
params.put("password", "my_password");
return params;
}
I would like to pass variables instead of "hard coded" strings...
First I tried to put my Map of params as a member of my class, but class members are not avaible in the getParams() method.
Maybe I could use a singleton class to wich I could give the parameters I want to pass and get them back using its instance in the getParams() method ? But I don't think that it would be the right manner.
Below is the hole code of my Volley's request :
RequestQueue queue = VolleySingleton.getInstance().getRequestQueue();
String url = "https://theUrlToRequest";
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
JSONObject mainObject = null;
try {
Log.i("app", "Result = " + response);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
Log.i("app", "Fail on Login" + error.toString());
}
}
) {
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("login", "my_login");
params.put("password", "my_password");
return params;
}
};
queue.add(postRequest);
In that case , you can create a Class extends StringRequest. Add an attr to store params and return it in getParams();
MyStringRequest extends StringRequest{
private Map params = new HashMap();
public MyStringRequest (Map params,int mehotd,String url,Listener listenr,ErrorListener errorListenr){
super(mehotd,url,listenr,errorListenr)
this.params = params
}
#Override
protected Map<String, String> getParams(){
return params;
}
}
RequestQueue queue = VolleySingleton.getInstance().getRequestQueue();
String url = "https://theUrlToRequest";
Map<String, String> params = new HashMap<String, String>();
params.put("login", "my_login");
params.put("password", "my_password");
MyStringRequest postRequest = new MyStringRequest (params ,Request.Method.POST, url,
new Response.Listener<String>(){
},
new Response.ErrorListener(){
}
);
queue.add(postRequest);

How to set custom header in Volley Request

How can custom headers be set for a Volley request? At the moment, there is way to set body content for a POST request. I've a simple GET request, but I need to pass the custom headers alongwith. I don't see how JsonRequest class supports it. Is it possible at all?
The accepted answer with getParams() is for setting POST body data, but the question in the title asked how to set HTTP headers like User-Agent. As CommonsWare said, you override getHeaders(). Here's some sample code which sets the User-Agent to 'Nintendo Gameboy' and Accept-Language to 'fr':
public void requestWithSomeHttpHeaders() {
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://www.somewebsite.com";
StringRequest getRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
Log.d("Response", response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
Log.d("ERROR","error => "+error.toString());
}
}
) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("User-Agent", "Nintendo Gameboy");
params.put("Accept-Language", "fr");
return params;
}
};
queue.add(getRequest);
}
It looks like you override public Map<String, String> getHeaders(), defined in Request, to return your desired HTTP headers.
If what you need is to post data instead of adding the info in the url.
public Request post(String url, String username, String password,
Listener listener, ErrorListener errorListener) {
JSONObject params = new JSONObject();
params.put("user", username);
params.put("pass", password);
Request req = new Request(
Method.POST,
url,
params.toString(),
listener,
errorListener
);
return req;
}
If what you want to do is edit the headers in the request this is what you want to do:
// could be any class that implements Map
Map<String, String> mHeaders = new ArrayMap<String, String>();
mHeaders.put("user", USER);
mHeaders.put("pass", PASSWORD);
Request req = new Request(url, postBody, listener, errorListener) {
public Map<String, String> getHeaders() {
return mHeaders;
}
}
You can see this solution. It shows how to get/set cookies, but cookies are just one of the headers in a request/response. You have to override one of the Volley's *Request classes and set the required headers in getHeaders()
Here is the linked source:
public class StringRequest extends com.android.volley.toolbox.StringRequest {
private final Map<String, String> _params;
/**
* #param method
* #param url
* #param params
* A {#link HashMap} to post with the request. Null is allowed
* and indicates no parameters will be posted along with request.
* #param listener
* #param errorListener
*/
public StringRequest(int method, String url, Map<String, String> params, Listener<String> listener,
ErrorListener errorListener) {
super(method, url, listener, errorListener);
_params = params;
}
#Override
protected Map<String, String> getParams() {
return _params;
}
/* (non-Javadoc)
* #see com.android.volley.toolbox.StringRequest#parseNetworkResponse(com.android.volley.NetworkResponse)
*/
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
// since we don't know which of the two underlying network vehicles
// will Volley use, we have to handle and store session cookies manually
MyApp.get().checkSessionCookie(response.headers);
return super.parseNetworkResponse(response);
}
/* (non-Javadoc)
* #see com.android.volley.Request#getHeaders()
*/
#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>();
}
MyApp.get().addSessionCookie(headers);
return headers;
}
}
And MyApp class:
public class MyApp extends Application {
private static final String SET_COOKIE_KEY = "Set-Cookie";
private static final String COOKIE_KEY = "Cookie";
private static final String SESSION_COOKIE = "sessionid";
private static MyApp _instance;
private RequestQueue _requestQueue;
private SharedPreferences _preferences;
public static MyApp get() {
return _instance;
}
#Override
public void onCreate() {
super.onCreate();
_instance = this;
_preferences = PreferenceManager.getDefaultSharedPreferences(this);
_requestQueue = Volley.newRequestQueue(this);
}
public RequestQueue getRequestQueue() {
return _requestQueue;
}
/**
* Checks the response headers for session cookie and saves it
* if it finds it.
* #param headers Response Headers.
*/
public final void checkSessionCookie(Map<String, String> headers) {
if (headers.containsKey(SET_COOKIE_KEY)
&& headers.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) {
String cookie = headers.get(SET_COOKIE_KEY);
if (cookie.length() > 0) {
String[] splitCookie = cookie.split(";");
String[] splitSessionId = splitCookie[0].split("=");
cookie = splitSessionId[1];
Editor prefEditor = _preferences.edit();
prefEditor.putString(SESSION_COOKIE, cookie);
prefEditor.commit();
}
}
}
/**
* Adds session cookie to headers if exists.
* #param headers
*/
public final void addSessionCookie(Map<String, String> headers) {
String sessionId = _preferences.getString(SESSION_COOKIE, "");
if (sessionId.length() > 0) {
StringBuilder builder = new StringBuilder();
builder.append(SESSION_COOKIE);
builder.append("=");
builder.append(sessionId);
if (headers.containsKey(COOKIE_KEY)) {
builder.append("; ");
builder.append(headers.get(COOKIE_KEY));
}
headers.put(COOKIE_KEY, builder.toString());
}
}
}
In Kotlin,
You have to override getHeaders() method like :
val volleyEnrollRequest = object : JsonObjectRequest(GET_POST_PARAM, TARGET_URL, PAYLOAD_BODY_IF_YOU_WISH,
Response.Listener {
// Success Part
},
Response.ErrorListener {
// Failure Part
}
) {
// Providing Request Headers
override fun getHeaders(): Map<String, String> {
// Create HashMap of your Headers as the example provided below
val headers = HashMap<String, String>()
headers["Content-Type"] = "application/json"
headers["app_id"] = APP_ID
headers["app_key"] = API_KEY
return headers
}
}
Looking for solution to this problem as well.
see something here: http://developer.android.com/training/volley/request.html
is it a good idea to directly use ImageRequest instead of ImageLoader? Seems ImageLoader uses it internally anyway. Does it miss anything important other than ImageLoader's cache support?
ImageView mImageView;
String url = "http://i.imgur.com/7spzG.png";
mImageView = (ImageView) findViewById(R.id.myImage);
...
// Retrieves an image specified by the URL, displays it in the UI.
mRequestQueue = Volley.newRequestQueue(context);;
ImageRequest request = new ImageRequest(url,
new Response.Listener() {
#Override
public void onResponse(Bitmap bitmap) {
mImageView.setImageBitmap(bitmap);
}
}, 0, 0, null,
new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
mImageView.setImageResource(R.drawable.image_load_error);
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new Map<String, String>();
params.put("User-Agent", "one");
params.put("header22", "two");
return params;
};
mRequestQueue.add(request);
try this
{
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
String bearer = "Bearer ".concat(token);
Map<String, String> headersSys = super.getHeaders();
Map<String, String> headers = new HashMap<String, String>();
headersSys.remove("Authorization");
headers.put("Authorization", bearer);
headers.putAll(headersSys);
return headers;
}
};
You can make a custom Request class that extends the StringRequest and override the getHeaders() method inside it like this:
public class CustomVolleyRequest extends StringRequest {
public CustomVolleyRequest(int method, String url,
Response.Listener<String> listener,
Response.ErrorListener errorListener) {
super(method, url, listener, errorListener);
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("key1","value1");
headers.put("key2","value2");
return headers;
}
}
public class CustomJsonObjectRequest extends JsonObjectRequest
{
public CustomJsonObjectRequest(int method, String url, JSONObject jsonRequest,Response.Listener listener, Response.ErrorListener errorListener)
{
super(method, url, jsonRequest, listener, errorListener);
}
#Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put("AppId", "xyz");
return headers;
}
}
As addition I'd like to share something I found regarding the Content-Type:
On top of
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
.
.
.
return params;
}
I had to add:
#Override
public String getBodyContentType() {
return /*(for exmaple)*/ "application/json";
}
Don't ask me why, I just thought it might help some others that can't get the Content-Type set right.
Here is setting headers from github sample:
StringRequest myReq = new StringRequest(Method.POST,
"http://ave.bolyartech.com/params.php",
createMyReqSuccessListener(),
createMyReqErrorListener()) {
protected Map<String, String> getParams() throws
com.android.volley.AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("param1", num1);
params.put("param2", num2);
return params;
};
};
queue.add(myReq);
try this
public void VolleyPostReqWithResponseListenerwithHeaders(String URL,final Map<String, String> params,final Map<String, String> headers,Response.Listener<String> responseListener) {
String url = URL;
Log.i("url:", ":" + url);
StringRequest mStringRequest = new StringRequest(Request.Method.POST,
url, responseListener, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// error
//Log.d("Error.Response", error.getLocalizedMessage());
}
}){
#Override
protected Map<String, String> getParams() {
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers;
}
};
mStringRequest.setRetryPolicy(new DefaultRetryPolicy(
60000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
mStringRequest.setShouldCache(true);
// dialog.show();
SingletonRequestQueue.getInstance(context).addToRequestQueue(mStringRequest);
}
That is my code, dont forget = object: if don't put don't works
val queue = Volley.newRequestQueue(this)
val url = "http://35.237.133.137:8080/lamarrullaWS/rest/lamarrullaAPI"
// Request a string response from the provided URL.
val jsonObjectRequest = object: JsonObjectRequest(Request.Method.GET, url, null,
Response.Listener { response ->
txtPrueba.text = "Response: %s".format(response.toString())
},
Response.ErrorListener { txtPrueba.text = "That didn't work!" }
)
{
#Throws(AuthFailureError::class)
override fun getHeaders(): Map<String, String> {
val headers = HashMap<String, String>()
headers.put("Content-Type", "application/json")
return headers
}
}
queue.add(jsonObjectRequest)

Categories

Resources