I've seen others come across this problem, but none of the posts have been able to assist me. I'm attempting to use Volley for my REST call library, and when I'm attempting to use a Put call with a JSON Object as a parameter, I'm getting error with: org.json.JSONException: End of input at character 0 of.
Here is the code:
protected void updateClientDeviceStatus(Activity activity, final int status) {
JSONObject jsonParams = new JSONObject();
try {
jsonParams.put("statusId", String.valueOf(status));
} catch (JSONException e1) {
e1.printStackTrace();
}
Log.i(LOG_TAG, "json: " + jsonParams.toString());
String url = Constants.API_URL + "client/device/" + getDeviceId();
// Request a response from the provided URL.
JsonObjectRequest request = new JsonObjectRequest
(Request.Method.PUT, url, jsonParams, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i(LOG_TAG, "updated client status");
Log.i(LOG_TAG, "response: " + response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i(LOG_TAG, "error with: " + error.getMessage());
if (error.networkResponse != null)
Log.i(LOG_TAG, "status code: " + error.networkResponse.statusCode);
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("User-Agent", getUserAgent());
params.put("X-BC-API", getKey());
return params;
}
#Override
public String getBodyContentType() {
return "application/json";
}
};
request.setRetryPolicy(new DefaultRetryPolicy(20000, 3, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MySingleton.getInstance(activity).addToRequestQueue(request);
}
}
The jsonParams log displays:
json: {"statusId":"1"}
Is there another setting that I'm missing? It appears that the request can't parse the JSON Object. I even tried creating a HashMap and then using that to create a JSON Object, but I still get the same result.
I also have encountered this issue.
It's not necessarily true that this is because a problem on your server side - it simply means that the response of the JsonObjectRequest is empty.
It could very well be that the server should be sending you content, and the fact that its response is empty is a bug. If, however, this is how the server is supposed to behave, then to solve this issue, you will need to change how JsonObjectRequest parses its response, meaning creating a subclass of JsonObjectRequest, and overriding the parseNetworkResponse to the example below.
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
JSONObject result = null;
if (jsonString != null && jsonString.length() > 0)
result = new JSONObject(jsonString);
return Response.success(result,
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
Keep in mind that with this fix, and in the event of an empty response from the server, the request callback will return a null reference in place of the JSONObject.
Might not make sense but nothing else worked for me but adding a content-type header
mHeaders.put("Content-Type", "application/json");
In my case it was simply the request I was sending(POST) was not correct. I cross-checked my fields and noted that there was a mismatch, which the server was expecting to get thus the error->end of input at character 0 of...
I had the same problem, I fixed it by creating a custom JsonObjectRequest that can catch a null or empty response :
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);
}
public CustomJsonObjectRequest(String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
super(url, jsonRequest, listener, errorListener);
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
JSONObject result = null;
if (jsonString != null && jsonString.length() > 0)
result = new JSONObject(jsonString);
return Response.success(result,
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
Then just replace the default JsonObjectRequest by this one !
You need to check if the server response is not empty. Maybe it could be a emtply String "".
if (response.success()) {
if (response.getData() == null) {
return null;
} else if (response.getData().length() <= 0){
return null;
}
// Do Processing
try {
I have faced the same problem, there was just a small silly mistake that happened.
instead of
val jsonObject = JSONObject(response.body()?.string())
should be
val jsonObject = JSONObject(response.body()!!.string())
Related
I send the /getsms GET request to an API and I get the expected results on postman. However, when I try to make the same request through volley in java on android studio, it just doesn't get a response, I keep waiting and nothing happens.
I'm sure the API does get the request since the expected changes occur when I send the data associated with the get request.
So I'm at a loss as to why exactly it doesn't get a response.
Java code:
final String url = "http://10.0.2.2:3000/myroute/getsms/"+frm;
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response) {
try {
String frm = response.getString("src_num");
String msg = response.getString("msg");
int id = response.getInt("id");
itemsAdapter.add(frm + ": " + msg);
Log.d("Response", response.toString());
}
catch (Exception err) {
Log.d("excpetion", err.toString());
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", error.toString());
}
}
);
API code:
router.get('/getsms/:dest_num', function (req, res) {
console.log("get oldest unsent sms from db");
let sql = "SELECT * FROM " + table + " WHERE " + "dest_num=" + req.params.dest_num + " AND sent=FALSE " + "ORDER BY id " + "LIMIT 1;";
console.log(sql);
db.mycon.query(sql, function (err, result) {
console.log("Result: " + JSON.stringify(result));
if(err){
res.send(err);
} else {
console.log("SENT!")
res.json(result);
}
});
});
Any help is appreciated.
UPDATE: So upon sifting through the logs I found this:
2020-01-15 22:07:23.481 11880-11880/com.example.sms D/Error.Response: com.android.volley.ParseError: org.json.JSONException: Value [{"id":4,"src_num":"321","dest_num":"1003435365","msg":"first message from server","time":100,"sent":0}] of type org.json.JSONArray cannot be converted to JSONObject
Apparently the response is received but Volley kicks when parsing. I cant see why this is happening. I don't see anything wrong with the JSON string. And is this really enough for it to not go into the onResponse function?
UPDATE2: So apparently that was indeed the problem and what was sent wasn't a JSONObject but a JSONArray. and just needed to change the datatypes accordingly.
So the code ended working with:
String url = "http://10.0.2.2:3000/myroute/getsms/" + frm;
JsonArrayRequest jsonObjectRequest = new JsonArrayRequest(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response_arr) {
try {
JSONObject response = response_arr.getJSONObject(0);
String frm = response.getString("src_num");
String msg = response.getString("msg");
int id = response.getInt("id");
itemsAdapter.add(frm + ": " + msg);
} catch (Exception err) {
System.out.println(err.toString());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", error.toString());
}
});
requestQueue.add(jsonObjectRequest);
Thanks to the comments for helping :)
You can try for The code given below and also add the request to the requestqueue of the new instance of RequestHandler.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray array = new JSONArray(response); //here is the mistake of parsing which will be removed after it is converted to the json object
JSONObject object = array.getJSONObject(0); //-----mistake
String frm = object.getString("src_num");
String msg = object.getString("msg");
int id = object.getInt("id");
itemsAdapter.add(frm + ": " + msg);
Log.d("Response", response.toString());
} catch (JSONException e) {
Log.d("excpetion", err.toString());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.response", err.toString());
}
});
new RequestHandler().addToRequestQueue(stringRequest);
Hope it helps !!
I have an API which send me a JSON object when I send a token to the server , I use GET method and I have to send token in body, not headers, it works in postman correctly when I put token in body but I have volley server error in android studio and I entered error response.here is my codes:
ant solution???? please
private void getFreightsFromServer()
{
final String url =" https://parastoo.app/api/driver-cargo-list";
JSONObject jsonData = new JSONObject();
String token = G.getString("token");
try
{
jsonData.put("token", token);
} catch (JSONException e)
{
e.printStackTrace();
}
Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>()
{
boolean isGet = false;
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public void onResponse(JSONObject response)
{
try
{
MyPost post = new MyPost();
JSONArray jsonArray = response.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject tempJsonObject = jsonArray.getJSONObject(i);
JSONObject jsonOriginCustomer = new JSONObject(tempJsonObject.getString("origin_customer"));
post.setOriginCity(jsonOriginCustomer.getString("customerCity"));
JSONObject jsonDestinationCustomer = new JSONObject(tempJsonObject.getString("destination_customer"));
Log.d("result", jsonDestinationCustomer.getString("customerCity"));
post.setDestinationCity(jsonDestinationCustomer.getString("customerCity"));
freightsList.add(post);
// isGet = true;
adapter.notifyDataSetChanged();
}
} catch (JSONException e)
{
e.printStackTrace();
}
}
};
Response.ErrorListener errorListener = new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
Toast.makeText(getContext(), error.toString(), Toast.LENGTH_LONG).show();
Log.d("jdbvdc", error.toString());
error.printStackTrace();
}
};
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, jsonData, listener, errorListener);
Log.d("fhdhdcf",jsonData.toString());
final int socketTimeout = 100000;
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
request.setRetryPolicy(policy);
AppSingleton.getInstance(getContext()).addToRequestQueue(request);
}
Please show the error message you have. Also I am not sure how ok it is to send something in a body of a GET request. This answer might help you:
HTTP GET with request body
It's better to use post method for this type of request.
But still if you want to use GET method then you should have to pass token in the URL.
Below is an example
final String username = etUname.getText().toString().trim();
final String password = etPass.getText().toString().trim();
URLline = "https://demonuts.com/Demonuts/JsonTest/Tennis/loginGETrequest.php?username="+username+"&password="+password;
I have method in which i am making a volley request and depending on the response I need to change a global boolean variable but for some reason the variable only gets changed after the method is executed completely giving me wrong data for the variable. I need to somehow changed the variable only after the response is recieved.. please help me with it
I need to change the value of variable 'chk' on response but it does not change.
public boolean checkSourceCode() {
pDialog.setMessage("Please Wait ...");
pDialog.show();
final String entered_source_code = source_code.getText().toString();
if(entered_source_code!=null || !entered_source_code.isEmpty()) {
testString = entered_source_code;
final StringRequest sr = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String web_response) {
try {
response = new JSONObject(web_response);
Log.e("Resp SUCCESS", "" + response);
} catch (JSONException e) {
e.printStackTrace();
}
try {
hasBeenValidated = true;
if (response.getBoolean("success")) {
Log.e("Resp SUCCESS", "" + response);
validateCode = true;
chk=true; // THIS VALUE DOES NOT CHANGE ON FIRST CALL OF THE METHOD HOWEVER ON SECOND TIME CALLING THE METHOD IT CHANGED
// Utils.reference_id = source_code.getText().toString().trim();
pDialog.hide();
input_layout_source_code.setError(null);
input_layout_source_code.setErrorEnabled(false);
Utils.reference_id = source_code.getText().toString().trim();
source_code.setBackground(source_code.getBackground().getConstantState().newDrawable());
} else {
validateCode = false;
chk=false;// THIS VALUE DOES NOT CHANGE ON FIRST CALL OF THE METHOD HOWEVER ON SECOND TIME CALLING THE METHOD IT CHANGED
pDialog.hide();
input_layout_source_code.setErrorEnabled(true);
input_layout_source_code.setError("Invalid reference Id.");
Utils.reference_id = null;
Toast.makeText(getContext(), "Invalid reference Id", Toast.LENGTH_SHORT).show();
}
// chk = validateSourceCode();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
String json = null;
if (error instanceof NoConnectionError) {
String strerror = "No internet Access, Check your internet connection.";
displayMessage(strerror);
}
NetworkResponse response = error.networkResponse;
if (null != response && response.statusCode != 200) {
Log.e("Resp code", "" + response.statusCode);
displayMessage("Please contact administrator for error code " + response.statusCode);
}
if (response != null && response.data != null) {
switch (response.statusCode) {
case 400:
json = new String(response.data);
json = trimMessage(json, "message");
if (json != null) displayMessage(json);
break;
default:
json = new String(response.data);
json = trimMessage(json, "message");
if (json != null) displayMessage(json);
}
}
}
}
) {
#Override
public Request.Priority getPriority() {
return Priority.IMMEDIATE;
}
#Override
protected Map<String, String> getParams() {
Map<String, String> requestParams = new HashMap<String, String>();
requestParams.put("referral_code", entered_source_code);
// params.put("email", "abc#androidhive.info");
// params.put("password", "password123");
return requestParams;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Auth-Token", auth_token);
return params;
}
};
sr.setRetryPolicy(new DefaultRetryPolicy(
60000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// Adding request to request queue
MaintainRequestQueue.getInstance(mContext).addToRequestQueue(sr, "tag");
}
else{
pDialog.hide();
chk=true;// THIS VALUE DOES NOT CHANGE ON FIRST CALL OF THE METHOD HOWEVER ON SECOND TIME CALLING THE METHOD IT CHANGED
}
Toast.makeText(mContext, String.valueOf(chk), Toast.LENGTH_LONG).show();
return chk;
}
chk variable can not reinitialize again inside a thread
try this
setchk(boolean chk)
{
this.chk=chk;
}
and call it from request method;
Your variable inside the volley request is not initialized by the time you reach: Toast.makeText(mContext, String.valueOf(chk), Toast.LENGTH_LONG).show(); Use a get method to obtain the chk value within volley and call that getter where you need it.
Hi guys I do not know how to read the actual detailed error message from the server, all I am getting is E/Volley: [73767] BasicNetwork.performRequest: Unexpected response code 500 for https://xxxx.com/xxxxx I saw people adding a onErrorResponse listener but mine isnt working so im clearly missing something, below is my code, any help is appreciated.
Request:
JSONObject jsonFavorites = new JSONObject();
String userId = Integer.toString(2);
String waypointID = Integer.toString(eventInfo.waypointId);
String waypointType = Integer.toString(eventInfo.stopType);
try {
jsonFavorites.put("action", favoriteAction);
jsonFavorites.put("uid", userId);
jsonFavorites.put("waypointid", waypointID);
jsonFavorites.put("waypoint_type", waypointType);
//fetchData(bounds);
} catch (Exception e) {
}
try{
GetUserFavoritesRequest favoritesRequest = new GetUserFavoritesRequest(jsonFavorites, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//Parse the response that was received from the server.
Log.d("Maps:", " Parsing Response");
try {
Log.i("tagconvertstr", "[" + response + "]");
//List<String> allFavorites = new ArrayList<String>();
JSONArray cast = new JSONArray(response);
if(userFavoritewaypointId.contains(eventInfo.waypointId)){
favoriteAction = "remove";
infoFavoriteButton.setImageResource(R.drawable.favorites_disabled);
}else{
favoriteAction = "add";
infoFavoriteButton.setImageResource(R.drawable.favorites);
}
finished = true;
} catch (JSONException e) {
//adding or removing favorites was unsuccessful.
Log.d("Maps:", " Failed getting a response from server for adding or removing favorites");
e.printStackTrace();
//Set the finished flag to true to let everyone know that we
//finished receiving a response from the server.
finished = true;
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Parse the response that was received from the server.
NetworkResponse networkResponse = error.networkResponse;
if (networkResponse != null) {
Log.e("Volley", "Error. HTTP Status Code:"+networkResponse.statusCode);
}
if (error instanceof TimeoutError) {
Log.e("Volley", "TimeoutError");
}else if(error instanceof NoConnectionError){
Log.e("Volley", "NoConnectionError");
} else if (error instanceof AuthFailureError) {
Log.e("Volley", "AuthFailureError");
} else if (error instanceof ServerError) {
Log.e("Volley", "ServerError");
} else if (error instanceof NetworkError) {
Log.e("Volley", "NetworkError");
} else if (error instanceof ParseError) {
Log.e("Volley", "ParseError");
}
Log.d("Maps:", " Error: " + error.getMessage());
finished = true;
}
});
RequestQueue queue = Volley.newRequestQueue(getActivity());
queue.add(favoritesRequest);
} catch (Exception e) {
//We failed to start a login request.
Log.d("Maps:", " Failed to start response for adding or removing favorites");
//Set the finished flag to true to let everyone know that we
//finished receiving a response from the server.
finished = true;
}
GetUserFavoritesRequest.java
public class GetUserFavoritesRequest extends StringRequest {
private static final String LOGIN_REQUEST_URL = "https://xxxx.com/xxxxx";
private Map<String, String> params;
public GetUserFavoritesRequest(JSONObject getFavorites, Response.Listener<String> listener, Response.ErrorListener errorListener){
super(Request.Method.POST, LOGIN_REQUEST_URL, listener, null);
params = new HashMap<>();
try {
if(getFavorites.get("action").toString().equals("get")){
Log.d("Maps: ", "Looks like we are retrieving a list of favorite waypoints");
params.put("action", getFavorites.get("action").toString());
params.put("uid", getFavorites.get("uid").toString());
}else if(getFavorites.get("action").toString().equals("add")){
Log.d("Maps: ", "Looks like we are adding a favorite waypoint" + getFavorites);
params.put("action", getFavorites.get("action").toString());
params.put("uid", getFavorites.get("uid").toString());
params.put("waypointid", getFavorites.get("waypointid").toString());
params.put("waypoint_type", getFavorites.get("waypoint_type").toString());
}else if(getFavorites.get("action").toString().equals("remove")) {
Log.d("Maps: ", "Looks like we are removing a favorite waypoint" + getFavorites);
params.put("action", getFavorites.get("action").toString());
params.put("uid", getFavorites.get("uid").toString());
params.put("waypointid", getFavorites.get("waypointid").toString());
params.put("waypoint_type", getFavorites.get("waypoint_type").toString());
}
}catch (Exception e){
}
}
#Override
public Map<String, String> getParams() {
return params;
}
}
I think there might be a mistake in GetUserFavoritesRequest's constructor
super(Request.Method.POST, LOGIN_REQUEST_URL, listener, null);
change null to errorListener.
I got an jsonarray like:
[{
"color": -1,
"fill": false,
"id": 1,
"radius": 154.613,
"shapeText": "",
"shapeType": "circle",
"x1": 141.172,
"x2": 0,
"y1": 231.188,
"y2": 0
}, {
"color": -4569601,
"fill": false,
"id": 2,
"radius": 0,
"shapeText": "",
"shapeType": "rectangle",
"x1": 512.656,
"x2": 606.781,
"y1": 305.25,
"y2": 413.502
}]
and I try to do POST to the server but I fail :[
I already get an jsonarray frm the server and I also did POST but for jsonobject to the server but I couldn't make it POST Jsonarray :[, anyone got any idea how to do it?
public class JSONPostArrayRequest extends JsonRequest<JSONObject> {
JSONArray params;
public JSONPostArrayRequest(String url, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener, JSONArray params) {
super(Method.POST, url, null, listener, errorListener);
this.params=params;
}
#Override
public byte[] getBody() {
if ( this.params != null && this.params.length() > 0) {
return encodeParameters( this.params, getParamsEncoding());
}
return null;
}
private byte[] encodeParameters(JSONArray params, String paramsEncoding) {
try {
return params.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}
#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));
}
}
}
and my request done with this code:
public void updateDraw(ArrayList<Shape> shapes) {
JSONArray jsonArrayShapes = new JSONArray();
Log.d("START OF JSON ARRAY ", shapes.toString());
for (Shape shape : shapes) {
try {
JSONObject jsonObjectShape = new JSONObject();
jsonObjectShape.put("color", String.valueOf(shape.getColor()));
jsonObjectShape.put("fill", String.valueOf(shape.isFill()));
jsonObjectShape.put("radius", String.valueOf(shape.getRadius()));
jsonObjectShape.put("shapeText", String.valueOf(shape.getShapeText()));
jsonObjectShape.put("shapeType", String.valueOf(shape.getShapeType()));
jsonObjectShape.put("x1", String.valueOf(shape.getX1()));
jsonObjectShape.put("x2", String.valueOf(shape.getX2()));
jsonObjectShape.put("y1", String.valueOf(shape.getY1()));
jsonObjectShape.put("y2", String.valueOf(shape.getY2()));
jsonObjectShape.put("id", String.valueOf(shape.getId()));
jsonArrayShapes.put(jsonObjectShape);
} catch (JSONException e) {
e.printStackTrace();
}
Log.d("JSONARRAY = ", jsonArrayShapes.toString());
}
String shapeUrl = Main.GROUPS_URL + "/" + id + "/shape";
Log.d("URL = ", shapeUrl);
JSONPostArrayRequest jsonPostArrayRequest = new JSONPostArrayRequest(shapeUrl,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("onErrorResponse ", error.toString());
}
}, jsonArrayShapes);
requestQueue.add(jsonPostArrayRequest);
}
You aren't passing your JSONArray into the request.
super(Method.POST, url, null, listener, errorListener);
That null parameter, as per the documentation
A JSONArray to post with the request. Null is allowed and indicates no parameters will be posted along with request.
Therefore, I don't see why you need to extend JsonRequest, or especially why you typed it with <JSONObject>.
The JsonArrayRequest class already exists, you just need to give the JSONArray object as the third parameter there.