I am using Volley Library for JSON Parsing, while parsing the response coming is as below :
JSON RESPONSE :
{"category":{"420":{"key":420,"label":{"420":"Acacia"},"count":"1"},"421":{"key":421,"label":.....
We can see, at start of the response a symbol is coming  . How can I remove this symbol from Android side without converting it into string? Because of this symbol I am not able to get JSON Object.
CODE :
private void jsonRequestGetFilterData() {
utils.showDialog();
String url = Constants.FILTER_URL;
Log.e("URL", "" + url);
StringRequest eventoReq = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("RESPONSE", response);
utils.hideDialog();
try {
JSONObject jsonObject = new JSONObject(response);
Log.e("jsonObject",""+jsonObject);
JSONObject jsonObjectCategory = jsonObject.getJSONObject("category");
Log.e("jsonObjectCategory",""+jsonObjectCategory);
} catch (JSONException e) {
e.printStackTrace();
utils.hideDialog();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error: ", "" + error.getMessage());
utils.hideDialog();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("customer_id", pref.getString(Constants.SP_CUSTOMER_ID, ""));
params.put("store_id", pref.getString(Constants.SP_STORE_ID, ""));
params.put("currency_code", pref.getString(Constants.SP_CURRENCY_CODE, ""));
Log.e("customer_id",""+pref.getString(Constants.SP_CUSTOMER_ID, ""));
Log.e("store_id",""+pref.getString(Constants.SP_STORE_ID, ""));
Log.e("currency_code",""+pref.getString(Constants.SP_CURRENCY_CODE, ""));
return params;
}
};
eventoReq.setRetryPolicy(new DefaultRetryPolicy(
60000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
AppController.getInstance(FilterActivity.this).addToRequestQueue(eventoReq);
}
Your response starts with a byte-order mark (BOM). At the level where you're reading the response, you need to ensure that the stream or whatever you're using to do that knows the encoding of the response (apparently it's not auto-detecting it). When it knows the correct encoding, it should understand and handle the BOM.
Normally, this is handled via the Content-Type header in the response from the server, and that's where it should be fixed. But if for some reason you can't fix it there, usually there's an option when creating the read stream to force an encoding. Yours looks like UTF-8.
Don't just use substring or similar to skip over it. Other characters in the string may well have been interpreted incorrectly because the wrong encoding is being used. (This isn't just for obscure characters, the £ sign varies by encoding, as does the € and any number of others.)
More: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
Solution 1:
The characters  is the byte order mark , so you should check your encoding (UTF-8 with or without BOM).
Solution 2:
You can convert response string to UTF-8 like,
#Override
public void onResponse(String response) {
try {
response=new String(response.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Log.e("RESPONSE", response);
...................
}
I find a simplest solution for my question. Put below line of code when you are sending params for POST Request.
Code Here :
params.put("Content-Type", "application/json; charset=utf-8");
Full Code :
----------
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json; charset=utf-8");
params.put("username", email.getText().toString().trim());
params.put("password", pwd.getText().toString().trim());
return params;
}
Related
Peeps, I have some problem in understanding the working of volley library, so answer with proper material which can guide me to unobserved aspects of volley is what I am looking forward to.
How does my POST parameters are bind in network request. When I send params after overriding getParams() and by sending jsonObject directly in network request I don't receive any response but some server errors.
Since I am testing my backend on Postman, what postman actually does(my Observation) is it bind the params in url itself. When I copy paste the url in my android code it responds positively.
So, should I code to append my params to url or there's another way round?
I have alredy tried making changes to getHeaders() but it doesn't respond too!
You should use a JsonObjectRequest with a jsonObject containing all your params.
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "8327483274823");
JSONObject jsonObject = new JSONObject(params);
JsonObjectRequest req = new JsonObjectRequest(URL,jsonObject ,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
//Do stuff here
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Handle Errors here
}
});
I have teaching myself how to develop Android applications and I recently started using the Volley library for networking. I have been able to send basic requests with it. I was experimenting with Pocket's API to see if my app could fetch the items. Their documentation page mentions that I have to send a JSON request like so
POST /v3/oauth/request HTTP/1.1
Host: getpocket.com
Content-Type: application/json; charset=UTF-8
X-Accept: application/json
{"consumer_key":"1234-abcd1234abcd1234abcd1234",
"redirect_uri":"pocketapp1234:authorizationFinished"}
So I made a JSONObject in my app, added the key consumer_key with the value of my consumer key, then added in the key redirect_uri with its respective value. I sent this JSONObject as a request to the required URL as a POST request using Volley. The response code I received was 403, which is caused by a bad consumer key. I have double-checked the consumer key, so the problem lies with my request. How should I go about making the JSON request? Do I have to add the extra data, like Content-Type? If so, how?
If it is not too much, could you point me to a beginner-friendly resource on JSON, since I do not have much knowledge about web development?
Thank you.
What request methode do you use on your code? I am facing issue when using StringRequest method. Its work when use JsonObjectRequest method.
Here is how to create request besides on my experience.
Create Header Parameter
final Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
headers.put("X-Accept", "application/json");
headers.put("consumer_key", "your-consumer-key");
headers.put("redirect_uri", "https://kamus.nusagates.com");
Create JSONObject From headers
JSONObject obj = new JSONObject(headers);
Create JsonObjectRequest
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("https://getpocket.com/v3/oauth/request", obj, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//get all response data
Log.d("respon", String.valueOf(response));
try {
//get code from response
Log.d("respon code", response.getString("code"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers;
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
String server = String.valueOf(response.headers);
Log.d("header", server);
return super.parseNetworkResponse(response);
}
};
Add the request to The Queue
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
queue.add(jsonObjectRequest);
May this could help you solve your problem.
Cheers
I am trying to sent JSON format data (using Volley) from two EditText-views and a method that return unique Device ID to a URL from my Android application and I receive
"[8970] BasicNetwork.performRequest: Unexpected response code 401 for https://gorountsiallyetlasornall:5wxGq5UNlY6wdWmNAyYPVVrN#bulberadev.cloudant.com/notebook"
Here is My method:
private void doPost() {
final String url = "https://gorountsiallyetlasornall:5wxGq5UNlY6wdWmNAyYPVVrN#bulberadev.cloudant.com/notebook";
final String deviceId = getDeviceId(getApplicationContext());
try {
try {
JSONObject jsonObject = new JSONObject();
String title = editTitle.getText().toString();
String content = editContent.getText().toString();
jsonObject.put("title", title);
jsonObject.put("content", content);
jsonObject.put("deviceId", "<" + deviceId + ">");
} catch (JSONException e) {
e.printStackTrace();
}
requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,
url, 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) {
// Log.e("VOLLEY", "ERROR");
}
});
requestQueue.add(jsonObjectRequest);
} catch (Exception e) {
e.printStackTrace();
}
}
it should be in a format :
{
"title":"Birth day",
"content":"Buy a gift for my mom!",
"deviceId":"<Device ID>"
}
A 401 is an Unauthorized error.
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error
This means that the user and password is not getting recognized. You're providing it by means of the URL, but this only works for the browser. If the service you're using accepts Basic HTTP authorization headers, this code will provide you the needed headers:
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
String creds = String.format("%s:%s","USERNAME","PASSWORD");
String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT);
params.put("Authorization", auth);
return params;
}
Original code from https://stackoverflow.com/a/18980454/3286819
Of course, username and password needs to be your own. In this case:
username: gorountsiallyetlasornall
password: 5wxGq5UNlY6wdWmNAyYPVVrN
URL: https://bulberadev.cloudant.com/notebook (notice I've removed the user and password)
Some more info: https://yakivmospan.wordpress.com/2014/04/04/volley-authorization/
Error 401 is an HTTP error for unauthorised. This is not a Volley or android related fault. In this case the URL you have provided
https://gorountsiallyetlasornall:5wxGq5UNlY6wdWmNAyYPVVrN#bulberadev.cloudant.com/notebook
Cannot be interpreted by Volley as a login either. This url is sometimes used by cURL and other tools to hardcode the username in password into the URI for Basic Authentication HTTP.
For this your username is gorountsiallyetlasornall and your password is 5wxGq5UNlY6wdWmNAyYPVVrN.
According to Basic Autentication, explained https://luckymarmot.com/paw/doc/HTTP_Basic_Auth
It needs to be converted to Base 64 then added to the header of the request.
I have converted your username and password into a Basic Auth base 64 encoded String for you bellow.
Z29yb3VudHNpYWxseWV0bGFzb3JuYWxsOjV3eEdxNVVObFk2d2RXbU5BeVlQVlZyTg==
Add this into your Volley header by extending a Volley request and overriding the function getHeaders to return a HashMap with the following key value pair.
"Authorization" , "Basic Z29yb3VudHNpYWxseWV0bGFzb3JuYWxsOjV3eEdxNVVObFk2d2RXbU5BeVlQVlZyTg"
Your request will now work.
Please let me know if you want a more detailed explanation.
PS. Hopefully the values you posted in your question is not your real username and password. If so, then don't do that in the future.
Every time I try to use POST method with Volley, I get sever error. I get null value in getCause, and some default value in getNetworkResponse.toString().
If I use GET method, this works fine (I get response from my url).
Can anybody help what can I do?
Map<String, String> jsonParams = new HashMap<String, String>();
jsonParams.put("teststr", "abd");
RequestQueue requestQueue = VolleySingleton.getInstance().getRequestQueue();
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.POST,
url,
new JSONObject(jsonParams),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Toast.makeText(getApplicationContext(), "Success"+response.toString(), Toast.LENGTH_LONG).show();
}catch(Exception e){
Toast.makeText(getApplicationContext(), "JSON ERROR", Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("abd", "Error: " + error
+ ">>" + error.networkResponse.statusCode
+ ">>" + error.networkResponse.data
+ ">>" + error.getCause()
+ ">>" + error.getMessage());
}
}) {
#Override
protected Map<String,String> getParams() {
HashMap<String, String> params = new HashMap<String, String>();
params.put("key", "value");
return params;
}
#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;
}
};
requestQueue.add(request);
Error Log:
Error:
Error: com.android.volley.ServerError>>404>>[B#42b1e0d0>>null>>null
UPDATE:
networkResponse.statusCode comes as 404, though the url is accessible (and return data if I just use GET method). If I remove header part in POST method, still the same.
the url:
<?php
$response = array();
$jsonString = file_get_contents('php://input');
$jsonObj = json_decode($jsonString, true);
if(!isset($jsonObj['teststr'])){
$response["msg"] = "No data.";
}else{
$response["msg"] = "Success: ".$jsonObj['teststr'];
}
echo json_encode($response);
?>
problem is your Queue.
change your volley code to this:
RequestQueue queue = Volley.newRequestQueue(this);
String URL = EndPoints.BASE_URL + "/call";
StringRequest request = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
Log.d("onResponse", response);
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
String errorMsg = "";
if(response != null && response.data != null){
String errorString = new String(response.data);
Log.i("log error", errorString);
}
}
}
) {
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("key_1","value_1");
params.put("key_2", "value_2");
Log.i("sending ", params.toString());
return params;
}
};
// Add the realibility on the connection.
request.setRetryPolicy(new DefaultRetryPolicy(10000, 1, 1.0f));
// Start the request immediately
queue.add(request);
and your php (laravel) code to this:
$response['success'] = true;
$response['user']['tell'] = $user->tell;
$response['user']['code'] = $user->code;
$response['user']['time'] = $time;
$response['user']['register_state'] = '1'
return response()->json($response, 200);
First, try to make sure your server works well.
You can use Postman(chrome plug-in) or any other way to send a post request to the url and see what it responses.
After make sure there's no problem with your server, let us solve the problem with volley.
There's some problem with JsonObjectRequest when you use POST method.
like this Volley JsonObjectRequest Post request not working.
I suggest you use StringRequest first and overwrite the getParams method like you did before. After you survive this task, you can try to write your own request, not very difficult but very useful.
I also suggest add request.setShouldCache(false) before requestQueue.add(request);. By default, volley saves the response in its cache and this behavior may cause some strange problem.
Well,I think you can first print the responseCode in your logcat
Add this code before add to queue
request.setRetryPolicy(new DefaultRetryPolicy(0, -1,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
sometimes, request is timeout before your php executed completely. so try this code. maybe can help
maybe it's related to your operator...
I have the same issue sending JasonObject with Volley.
I tested my app on 9-10 devices with two different operators.
The request on one operator returns an Error with everything null or blank data in it, on the other one everything works fine and I get my Response from API successfully.
I have no idea what do operators do that causes this problem...
Maybe they use some kind of firewall that blocks sending JsonObject.
I tried to display the response as a String and the error went off.
Use response.toString() wherever you want to display the error or use it.
In my case, the answer is retry policy setting.
I put 30 seconds the timeout value, it should be 30000, not 30.
try to increase timeout. i had the same issue and the request timeout was the problem.
How to make a JSON request in volley where I need to send an authentification header and JSON object in body and I expect only an status code 200 answer
JsonObjectRequest request = new JsonObjectRequest(
method,
url,
myJsonObject,
responseListener,
errorListener) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
String creds = String.format("%s:%s", login, password);
String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT);
headers.put("Authorization", auth);
return headers;
}
};
new Response.Listener<String>(){
#Override
public void onResponse(String response) {
Toast.makeText(getActivity(), response, 1000).show();
}
I tried different kinds of response listeners with string or JSON object, object, but always there is an error:
android volley org.json.JSONException: End of input at character 0 of
Or is there any other kind of request in volley which supports and json object and authentification header in body and response is just a http status code ?
I know its an old question but i thought i still answer this as my answer might help people in future -
You need to create a custom class that extends Request class and in that class override these methods
#Override
protected Response parseNetworkResponse(NetworkResponse response) {
return Response.success(response.statusCode, HttpHeaderParser.parseCacheHeaders(response));
}
#Override
protected void deliverResponse(Integer statusCode) {
mListener.onResponse(statusCode);
}
This is the heart and soul of the class.
For full code and explanation check out my blog on the topic -
Getting a server response status 200 from Android Volley library
link 1
Hope it helps,
Thanks
Thanks to Varundroid and Itai Hanski. It's correct, you just need to subclass the JsonObjectRequest.
For convenience here's my override:
public class MyJsonObjectRequest extends JsonObjectRequest {
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
// here's the new code, if jsonString.length() == 0 don't parse
if (jsonString.length() == 0) {
return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
}
// end of patch
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));
}
}
}
So I just use that instead of JsonObjectRequest.
Not too pretty, not too ugly.
The JsonObjectRequest is used when you expect the network response to be a JSON object. Since you're not expecting that, you shouldn't be using it.
Volley comes with a few predefined popular types of requests for ease of use, but you can always create your own. I suggest making a custom request based on JsonObjectRequest, but with a different implementation of the parseNetworkResponse() method that does not expect the response to be a JSON object, since you aren't receiving one. You can add any other changes you need there.
No need to create custom class which extends Request as #varundroid stated.
You can just override parseNetworkResponse method instead of onResponse method and return success response with empty JSONObject().
Following is the code I'm using to overcome the same problem you are facing. I hope this helps you too
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
if (response != null && response.data.length == 0)
return Response.success(new JSONObject(), null);
else
return super.parseNetworkResponse(response);
}