I want to send a DELETE request to an API to delete a city with the given id. In the API request documentation it says that the DELETE request requires as parameters the authentication token and the city id. When I run the code below I always get a com.android.volley.AuthFailureError.
Here's my code:
void deleteCity(String cityId, final VolleyResponseListener volleyResponseListener){
String url = baseUrl + "city";
try {
JSONObject params = new JSONObject();
params.put("token", token);
params.put("city_id", cityId);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.DELETE, url, params, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try{
String success = response.get("success").toString();
if(success.equals("true")){
volleyResponseListener.onResponse();
}else{
String errorMessage = response.get("errorMessage").toString();
throw new Exception(errorMessage);
}
} catch (Exception e) {
volleyResponseListener.onError(e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
volleyResponseListener.onError("Volley Error");
}
});
requestQueue.add(jsonObjectRequest);
}catch (JSONException e){
volleyResponseListener.onError("Param error");
}
}
UPDATE:
I solved the problem by adding the city id as a query in the HTTP request and sent the authentication token in the header. Here is the final code:
void deleteCity(String cityId, final VolleyResponseListener volleyResponseListener){
String url = baseUrl + "city?city_id="+cityId;
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.DELETE, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try{
String success = response.get("success").toString();
if(success.equals("true")){
volleyResponseListener.onResponse();
}else{
String errorMessage = response.get("errorMessage").toString();
throw new Exception(errorMessage);
}
} catch (Exception e) {
volleyResponseListener.onError(e.getMessage());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
volleyResponseListener.onError("Volley 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("token", token);
return headers;
}
};
requestQueue.add(jsonObjectRequest);
}
I'm using JSONObject to parse the JSON file and get its contents. Everything goes fine but tags aren't showing in the RecyclerView.
Here's the code :
private void direct_url(){
v_title = findViewById(R.id.vid_title);
String url = kw_url_holder.getText().toString();
String server_tag_url = "https://server.com/json.json";
StringRequest request = new StringRequest(Request.Method.GET, server_tag_url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
String title,views,likes,dislikes,publishedon,duration;
JSONObject object=new JSONObject(response);
title = object.getString("title");
v_title.setText(title);
JSONArray tagsJsonArray = object.getJSONArray("tags");
for(int i=0; i<tagsJsonArray.length();i++){
try {
JSONObject tagObj = new JSONObject();
tagObj = tagsJsonArray.getJSONObject(i);
TagUrlResultsModel tagUrlResultsModel = new TagUrlResultsModel();
tagUrlResultsModel.setV_tags(tagObj.getString(String.valueOf(i)));
url_result.add(tagUrlResultsModel);
}catch (JSONException e){
e.printStackTrace();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("error",error.toString());
}
});
url_queue = Volley.newRequestQueue(tags.this);
url_queue.add(request);
}
The JSON:
{
"title": "The Title",
"tags": ["tag1", "tag2"]
}
An error in the logs:
Error: java.lang.String cannot be converted to JSONObject
The problem is inside your for loop in:
JSONObject tagObj = new JSONObject();
tagObj = tagsJsonArray.getJSONObject(i);
TagUrlResultsModel tagUrlResultsModel = new TagUrlResultsModel();
tagUrlResultsModel.setV_tags(tagObj.getString(String.valueOf(i)));
url_result.add(tagUrlResultsModel);
It should be
String tag;
tag = tagsJsonArray.getString(i);
TagUrlResultsModel tagUrlResultsModel = new TagUrlResultsModel();
tagUrlResultsModel.setV_tags(tag);
url_result.add(tagUrlResultsModel);
Using getString() instead of getJSONObject() as the content of that JSONArray is just strings.
That's why you are getting in that catch:
Error: java.lang.String cannot be converted to JSONObject
I want to get Infos from a Database. When i use a Query without parameters (e.g. "Select * from users;" my script works fine.
Now i have the following script which returns an empty Array. When i replace the $groupId in script with a string value (e.g. "Group1") it returns the expected Items.
<?php
$sql = "";
if($_SERVER['REQUEST_METHOD']== 'POST') {
$flag = array();
$groupId = $_POST['groupId'];
require_once('dbConnect.php');
$sql = "SELECT * FROM users where groupId = '$groupId'";
if($out = mysqli_query($con,$sql)){
//echo "Successfully Registered";
while($row = mysqli_fetch_array($out))
{
$flag[] = $row;
}
print(json_encode($flag));
}else{
echo "Could not register";
}
}else{
echo 'error';
}
//mysqli_close($con);
?>
When i call the following function with the hashmap hashMapGetNames.put("groupId", "Group#1");
then i get an empty array and the info: "No, Group ID is not set"
public ArrayList<String> get(String url, final HashMap<String, String> hashMap, final Context context) {
//Download the items from DB
final ArrayList<String> items = new ArrayList<>();
RequestQueue queue = Volley.newRequestQueue(context);
JSONObject parameters = new JSONObject(hashMap);
final JsonRequest<JSONArray> jsonArrayRequest = new
JsonRequest<JSONArray>(Request.Method.GET, url, parameters.toString(),
new com.android.volley.Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
if(jsonArray == null){
Log.d("Downloader", "FAIL: NO NAMES FOUND");
}
else {
for (int zähler = 0; zähler < jsonArray.length(); zähler++){
try {
Log.d("Downloader", "sind bei zähler " + zähler);
JSONObject object = jsonArray.getJSONObject(zähler);
String name = object.getString("name");
Log.d("Name", name);
items.add(name);
}
catch (JSONException e) {
Log.d("Downloader", "Catching exception");
e.printStackTrace();
}
}
}
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Downloader", "Error: " + error.toString());
}
})
{
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Log.d("Downloader", "gettingParams");
return hashMap;
}
#Override
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
Log.d("Downloader", "parsing Network response");
try {
String jsonString = new String(response.data,
HttpHeaderParser
.parseCharset(response.headers));
Log.d("Downloader", "Parsing success");
return Response.success(new JSONArray(jsonString),
HttpHeaderParser
.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
Log.d("Downloader", e.toString());
return Response.error(new ParseError(e));
} catch (JSONException je) {
Log.d("Downloader", je.toString());
return Response.error(new ParseError(je));
}
}
};
queue.add(jsonArrayRequest);
return items;
}
So the Script seems right but the parameter does not reach the Script. Any Ideas where the error could hide?
EDIT: I edited the code like shown in the tutorial commented below and use the same dbConnect.php file. but it prints out error - so the problem still exist. That means that the Request Method is not "Post".
Android Monitor prints out:
parsing Network response
Downloader: Parsing success
Error: com.android.volley.ParseError: org.json.JSONException: End of input at character 0
try this code...
#Override
protected Map<String, String> getParams() throws AuthFailureError {
//Creating parameters
Map<String,String> params = new Hashtable<String, String>();
//Adding parameters
params.put("groupId", "122");
//returning parameters
return params;
}
Here I am trying to send my json array to mysql database.When I run this code I get this error:
com.android.volley.ParseError: org.json.JSONException: Value {"msg":false,"status":false} of type org.json.JSONObject cannot be converted to JSONArray
And here's my code:
private void insertToDb() {
billType = (invEstSwitch.isChecked() ? textViewEstimate : textViewInvoice)
.getText().toString();
try {
jsonObject.put("custInfo", custSelected.toString());
jsonObject.put("invoiceNo", textViewInvNo.getText().toString());
jsonObject.put("barcode", barCode.getText().toString());
jsonObject.put("desc", itemDesc.getText().toString());
jsonObject.put("weight", weightLine.getText().toString());
jsonObject.put("rate", rateAmount.getText().toString());
jsonObject.put("makingAmt", makingAmount.getText().toString());
jsonObject.put("net_rate", netRate.getText().toString());
jsonObject.put("itemTotal", itemtotal.getText().toString());
jsonObject.put("vat", textViewVat.getText().toString());
jsonObject.put("sum_total", textViewSum.getText().toString());
jsonObject.put("bill_type", billType);
jsonObject.put("date", textViewCurrentDate.getText().toString());
} catch (JSONException e) {
e.printStackTrace();
}
try {
itemSelectedJson.put(index, jsonObject);
index++;
} catch (JSONException e) {
e.printStackTrace();
}
final JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.POST, INVEST_URL, itemSelectedJson, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d("RESPONSE", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("JSON ERROR", error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json; charset=utf-8");
headers.put("Accept", "application/json");
return headers;
}
};
final RequestQueue queue = Volley.newRequestQueue(this);
queue.add(arrayRequest);
}
I also tried displaying the json array inside a text view.It displays the following json array.
[
{
"custInfo": "Ujwal 9975022560",
"rate": "24000",
"weight": "21.00000",
"desc": "GENTS ANGTHI 22k NO STONE",
"makingAmt": "200",
"sum_total": "RS.104188.92",
"vat": "RS.2042.92",
"itemTotal": "51073",
"barcode": "BQSP78BB",
"net_rate": "24200",
"date": "2015-12-01",
"invoiceNo": "1",
"bill_type": "Estimate"
},
{
"custInfo": "Ujwal 9975022560",
"rate": "24000",
"weight": "21.00000",
"desc": "GENTS ANGTHI 22k NO STONE",
"makingAmt": "200",
"sum_total": "RS.104188.92",
"vat": "RS.2042.92",
"itemTotal": "51073",
"barcode": "BQSP78BB",
"net_rate": "24200",
"date": "2015-12-01",
"invoiceNo": "1",
"bill_type": "Estimate"
}
]
I tested this json array on json lint.It is a valid JSON.
As suggested I changed to json object request.Now I am getting a Response it say RESPONSE: {"msg":false,"status":false} I get it at
public void onResponse(JSONObject response) { Log.d("RESPONSE", response.toString()); } what does that mean?
private void insertToDb() {
billType = (invEstSwitch.isChecked() ? textViewEstimate : textViewInvoice)
.getText().toString();
try {
jsonObject.put("custInfo", custSelected.toString());
jsonObject.put("invoiceNo", textViewInvNo.getText().toString());
jsonObject.put("barcode", barCode.getText().toString());
jsonObject.put("desc", itemDesc.getText().toString());
jsonObject.put("weight", weightLine.getText().toString());
jsonObject.put("rate", rateAmount.getText().toString());
jsonObject.put("makingAmt", makingAmount.getText().toString());
jsonObject.put("net_rate", netRate.getText().toString());
jsonObject.put("itemTotal", itemtotal.getText().toString());
jsonObject.put("vat", textViewVat.getText().toString());
jsonObject.put("sum_total", textViewSum.getText().toString());
jsonObject.put("bill_type", billType);
jsonObject.put("date", textViewCurrentDate.getText().toString());
} catch (JSONException e) {
e.printStackTrace();
}
try {
itemSelectedJson.put(index, jsonObject);
index++;
} catch (JSONException e) {
e.printStackTrace();
}
JSONObject jsonobj = new JSONObject();
try {
jsonobj.put("itemarray",itemSelectedJson);
} catch (JSONException e) {
e.printStackTrace();
}
final JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.POST, INVEST_URL, jsonobj, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("RESPONSE", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("JSONERROR",error.toString());
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json; charset=utf-8");
headers.put("Accept", "application/json");
return headers;
}
};
final RequestQueue queue = Volley.newRequestQueue(this);
queue.add(objectRequest);
}
As in log:
com.android.volley.ParseError: org.json.JSONException: Value
{"msg":false,"status":false}
Means Server is returning JSONObject instead of JSONArray as response String.
So, use JsonObjectRequest instead of JsonArrayRequest to make Volley request.
POST a JSONArray doesn't mean you need to call a JsonArrayRequest request.
Request depends on the type of the response you are expecting. You have to check the object type returned by your webservice and then adapt your request according to that.
In your specific case, the error log says you need to use a JsonObjectRequest instead of JsonArrayRequest.
And I final got it to work this is my current code
private void insertToDb() throws JSONException{
//createJsonArray();
final String jsonArray = itemSelectedJson.toString().trim();
StringRequest stringRequest = new StringRequest(Request.Method.POST, INVEST_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
display.setText("This is the "+response);
Toast.makeText(AddInvEst.this, "This is the response"+response, Toast.LENGTH_LONG).show();
Log.d("RESPONSE", response.toString().trim());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put(KEY_JSONARRAY,jsonArray);
return params;
}
};
RequestQueue requestQ =Volley.newRequestQueue(this);
requestQ.add(stringRequest);
}
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.