I would like to send and receive a Json Array with volley.
Now I can receive an array and it's ok but I don't know how to send a request (For example: with post method).
JsonArrayRequest arrayReq = new JsonArrayRequest(URL,
new Listener<JSONArray>() {
}
List<Map<String,String>> listMap = new ArrayList<Map<String, String>>();
Map<String,String> map = new HashMap<String,String>();
try {
map.put("email", customer.getEmail());
map.put("password",customer.getPassword());
} catch (Exception e) {
e.printStackTrace();
}
listMap.add(map);
String url = PersonalConstants.BASE_URL+"/url";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Request.Method.POST, url, String.valueOf(new JSONArray(listMap)),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
Log.d(App.TAG, jsonObject.toString());
}
}, new Response.ErrorListener (){
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d(App.TAG,volleyError.toString());
}
}
);
App.getInstance().getmRequestQueue().add(jsonObjectRequest);
Here is an example:
// Define the web service URL
final String URL = "http://www.someurl.com";
// POST params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("name", "raha tamjid");
// Define the POST request
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// Add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
How the POST request differs is that it takes a JSONObject as parameter.
EDIT 1:
If you have Volley installed as a library project in your IDE, then just define a new constructor
public JsonArrayRequest(int method, String url, JSONObject jsonRequest,
Listener<JSONArray> listener, ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener, errorListener);
}
inside the class JsonArrayRequest which is present in the Volley library code. Now you can use this to create JsonArrayRequest objects and add them to the RequestQueue.
EDIT 2:
1. Get the Volley library project from here. Download the project and set it up in your IDE.
2. Make the modification to the JsonRequest class (found in com.android.volley.toolbox namespace) as discussed in EDIT 1.
3. Delete the volley.jar from the libs folder of your APPLICATION PROJECT.
4. Now go to Project Properties -> Android -> Library and click on Add. From here select the Volley project. Clean & Rebuild.
5. Now in your APPLICATION PROJECT you can make a POST JsonArrayRequest just like how we make a POST JsonObjectRequest and get a JSONArray in the Response.
Create a class and extend JsonArrayRequest then override
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
params.put("name", "value");
return params;
}
and add a new constructor and in it call
super(Method.POST, url, null, listener, errorListener);
or use this class
public class PostJsonArrayRequest 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 PostJsonArrayRequest(String url, Response.Listener<JSONArray> listener, Response.ErrorListener errorListener) {
super(Method.POST, url, null, listener, errorListener);
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
params.put("name", "value");
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 (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
}
Create a new java class named JsonArrayPostRequest now you can use it like the previous request, just replace JSONArrayRequest with JsonArrayPostRequest and pass the correct parameters
public class JsonArrayPostRequest extends Request<JSONArray>{
private Map<String,String> mParam;
private Listener<JSONArray> mListener;
public JsonArrayPostRequest(String url,Listener<JSONArray> listener, ErrorListener errorListener,Map param) {
super(Request.Method.POST, url, errorListener);
mListener=listener;
mParam=param;
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
return mParam;
}
#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 (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
protected void deliverResponse(JSONArray response) {
mListener.onResponse(response);
}
}
USE:
JsonArrayPostRequest request = new JsonArrayPostRequest(URL,new Response.Listener<JSONArray>(),
new Response.ErrorListener() ,params);
Related
I want to update the "Pass" field using WebAPI, I have created an HTTP PUT Request using Asp.Net WEB API and Android Java with Volley.
through Postman it's updating field value but when I test through my App it's updating the blank value in DB.
Thanks in advance.
private void callPUTDataMethod(String name, String job) {
loadingPB.setVisibility(View.VISIBLE);
String url = URL;
RequestQueue queue = Volley.newRequestQueue(PassUpdt.this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.PUT, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
loadingPB.setVisibility(View.GONE);
jobEdt.setText("");
userNameEdt.setText("");
// on below line we are displaying a toast message as data updated.
Toast.makeText(PassUpdt.this, "Data Updated..", Toast.LENGTH_SHORT).show();
try {
JSONObject jsonObject = new JSONObject("Pass");
String output = "Password Updated";
responseTV.setText(output);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(PassUpdt.this, "Fail to update data..", Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("EmpCd", "P010");
params.put("Pass", "12345");
params.put("Content-Type", "application/json; charset=utf-8");
return params;
}
};
queue.add(jsonObjectRequest);
}
}
I sent request with postman its working, but volley doesn't work. I always get error! I searched stackoverflow volley returns error when response is empty but i added CustomJsonObjectRequest still the issue remains.
Error message
Volley org.json.JSONException: End of input at character 0 of
CustomJsonObjectRequest
public class CustomJsonObjectRequest extends JsonObjectRequest {
public CustomJsonObjectRequest(int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
super(method, url, jsonRequest, listener, errorListener);
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
if (response.data.length == 0) {
byte[] responseData = "{}".getBytes("UTF8");
response = new NetworkResponse(response.statusCode, responseData, response.headers, response.notModified);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return super.parseNetworkResponse(response);
}
}
Volley request
EcoElement ecoElement = ecoElementArrayList.get(position);
Map<String, String> params = new HashMap<String, String>();
params.put("Id", ecoElement.getId().toString());
params.put("Checked", ecoElement.getChecked().toString());
JSONObject ObjParams = new JSONObject(params);
try {
CustomJsonObjectRequest getRequest = new CustomJsonObjectRequest(Request.Method.PUT, "https://ourwebsite.sslbeta.de/api/gardenapi/updateecoelements", ObjParams,
response -> {
Toast.makeText(getContext(), ""+response, Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
},
error -> {
Toast.makeText(getContext(), ""+error.toString(), Toast.LENGTH_SHORT).show();
progressBar.setVisibility(View.GONE);
}
);
RequestQueueSingleton.getInstance(getContext()).addToRequestQueue(getRequest);
} catch (Exception e) {
Toast.makeText(getContext(), e.toString(), Toast.LENGTH_LONG).show();
}
Finally i was able to fix the issues after hours of searching. There were two reasons to this, first is that api was returning null/empty so CustomJsonObjectRequest fixed that, and then another issue is that i forgot to add authentication headers. that was a silly mistake i know!
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
headers.put("Authorization", "Bearer "+access_token);
return headers;
}
};
Here is the solution, just create this method and pass your value.
private void CustomJsonObjectRequest() {
String tag_string_req = "req__details";
StringRequest strReq = new StringRequest(Request.Method.POST, <API URL>, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
getPerspective().showErrorLogs(TAG, "Response Invest : " + response);
try {
// Parse your response here
} catch (Exception e) {
e.printStackTrace();
}
}
}, 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("Id", <ID VALUE HERE>);
params.put("Checked", <TRUE or FALSE>);
return params;
}
};
strReq.setRetryPolicy(new RetryPolicy() {
#Override
public void retry(VolleyError arg0) throws VolleyError {
}
#Override
public int getCurrentTimeout() {
return 0;
}
#Override
public int getCurrentRetryCount() {
return 0;
}
});
strReq.setShouldCache(false);
addToRequestQueue(strReq, tag_string_req);
}
Both ID and Checked must have String type.And create below methods in MainActivity:
private RequestQueue mRequestQueue;
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
Guys i need help am trying to post this data to my server here but it is returning an error, it seems to be working just fine in postman the problem comes in while trying to implement in android app using google's volley library.
Link to server script.
This is the screenshot of a successful post working in postman rest client:2
private void SaveDataToServer() {
StringRequest serverPostRequest = new StringRequest(Request.Method.POST, Config.SAVE_INVENTORY_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String json) {
try {
Toast.makeText(SelectItemsActivity.this, json.toString(), Toast.LENGTH_SHORT).show();
Log.e("RESPONSE FROM SERVER",json);
JSONObject dataJson=new JSONObject(json);
JSONObject myJson=dataJson.getJSONObject("status");
String status=myJson.getString("status_text");
if (status.equalsIgnoreCase("Success.")){
Toast.makeText(SelectItemsActivity.this, "Data saved Successfully", Toast.LENGTH_SHORT).show();
proggressShow.dismiss();
}else {
Toast.makeText(SelectItemsActivity.this, "An error occured while saving data", Toast.LENGTH_SHORT).show();
proggressShow.dismiss();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
}){
#Override
protected Map<String, String> getPostParams() {
HashMap<String, String> params = new HashMap<String, String>();
params.put("api_key",Config.API_KEY);
params.put("move_id", "1");
params.put("room_name", "Attic room");
params.put("item_name", "Halloween Broom");
params.put("item_id", "6");
Log.e("datat to server",params.toString());
return params;
}
};
saveDataRequest.add(serverPostRequest);
}
Try adding getHeaders method in your request
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
final HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type", "multipart/form-data");
return headers;
}
After adding this lines to my request headers i was able to successfully commit the database to my db.
Also i made sure i am using a stringRequest for a jsonRequest it does not work for reasons i do not know.
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type","application/x-www-form-urlencoded");
return headers;
}
I wan't send post from JsonArrayRequest to server and I found some answer and I trying it..
but I got error like this
this is my code
HashMap<String, String> params = new HashMap<String, String>();
public void JSON_DATA_WEB_CALL() {
jsonArrayRequest = new JsonArrayRequest(GET_JSON_DATA_HTTP_URL, new JSONObject(params),
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
JSON_PARSE_DATA_AFTER_WEBCALL(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("CUSTOM_HEADER", "Yahoo");
headers.put("ANOTHER_CUSTOM_HEADER", "Google");
return headers;
}
};
requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
how to fix that?
Use this custom class.
public class CustomJsonArrayRequest extends JsonRequest<JSONArray> {
/**
* Creates a new request.
* #param method the HTTP method to use
* #param url URL to fetch the JSON from
* #param jsonRequest A {#link JSONObject} 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 CustomJsonArrayRequest(int method, String url, JSONObject jsonRequest,
Response.Listener<JSONArray> listener, Response.ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
errorListener);
}
#Override
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
return Response.success(new JSONArray(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
}
Implementation in your case should be something like this:
HashMap<String, String> params = new HashMap<String, String>();
public void JSON_DATA_WEB_CALL() {
CustomJsonArrayRequest request = new CustomJsonArrayRequest (Request.Method.POST, GET_JSON_DATA_HTTP_URL, new JSONObject(params),
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
JSON_PARSE_DATA_AFTER_WEBCALL(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("CUSTOM_HEADER", "Yahoo");
headers.put("ANOTHER_CUSTOM_HEADER", "Google");
return headers;
}
};
requestQueue = Volley.newRequestQueue(this);
requestQueue.add(request);
}
I feel like this is a very basic concept missunderstanding. In my Android app I make HTTP requests using Volley lib. At first I made the requests through a JsonObjectRequest in the Activity code and worked right, but now I separated the request code in a class apart so I can call it from any Activity. The new class has a method that returns the requested JSONObject but any "json action" I do over the returned object ends in an error.
Here is the new class code, JSONRequests:
public class JSONRequests {
private JSONObject mResponse;
private String mURL = "https://myurl.com/";
public JSONObject getJSONObject(final String credentials, final String path) {
final JsonObjectRequest mRequest = new JsonObjectRequest(mURL.concat(path), null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
mResponse = response;
try {
Log.d("RESPONSE", mResponse.getString("id")); // It works here
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", "Basic " + credentials);
return headers;
}
};
MyApplication.getInstance().getRequestQueue().add(mRequest);
return mResponse;
}
}
And here is how I call getJSONObject from MyActivity:
JSONRequests mRequest = new JSONRequests();
JSONObject mInfo = mRequest.getJSONObject(mEncodedCredentials, mPath);
try {
Log.d("RESPONSE", mInfo.getString("id")); // This doesn't work
} catch (JSONException e) {
e.printStackTrace();
}
When in the Activity file, I used "response" as a JSONObject and it worked, but now separated it won't. I don't know if is a error with JSONObject or just that I'm not getting the returned object in the correct way. Thanks in advance.