Volley Server Error with null Network response - android

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.

Related

Remove symbol  from json response

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;
}

Volley not attaching parameters to my url via POST request with StringRequest

I am trying to use volley to add a score to my database. I have tested my URL with a POST request using Postman, I have also manually typed the URL with parameters in the android app to the POST request, and that works. so I assume that my issue is in my android code? Or do I have to use the getParams to manually build the url string?
the error I'm getting from my backend:
Error: ER_BAD_FIELD_ERROR: Unknown column 'undefined' in 'field list'
which makes me think that my parameters aren't getting initialized prior to the StringRequest being called.
public void submitHighScore(){
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
Toast.makeText(context, response , Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error
Toast.makeText(context, "Error: unable to submit Score " + error , Toast.LENGTH_SHORT).show();
}
}
){#Override
protected Map<String, String> getParams() throws com.android.volley.AuthFailureError
{
Map<String, String> params = new HashMap<String, String>();
params.put("playerName", "Android test");
params.put("playerScore", "3000");
return params;
}
};
HighScoreSingleton.getInstance(context).addToRequestQueue(postRequest);
For those who may or may not believe me about my code on my server side.
app.post('/api/highScore', function(req,res){
var con = mysql.createConnection({
host: "xxxx",
user: "xxxx",
password: "xxxx",
database: "xxxx"
});
if(req.query!=null){ //
console.log(typeof req.query.playerName);
con.query(`INSERT INTO xxxx (playerScore, playerName) VALUES
(${req.query.playerScore}, "${req.query.playerName}" )`, // async, runs callback aka function
function(err,rows){
if(err) throw err;
res.setHeader('Content-Type', 'text/plain');
res.send('Updated High Score');
});
con.end();
}
});
Thank you in advance, It's very possible I'm overlooking something very simple, otherwise I will just modify my URL in my StringRequest as this seems a bit silly, given the getParams method.
I Hope this will work for you.
I think you need to add header
Override this method.
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = super.getHeaders();
if(params==null)params = new HashMap<>();
params.put("Content-Type","text/plain");
return params;
}

consume Asp.net MVC api from android volley

i am trying to consume a MVC 4 api from my android application
i am using Volley library and it work fine to get data from server
the problem is when i try to send data to the web service which i understand it should be done by using post Method and JsonObjectRequest
my method in MVC Api is :
public class ItemController : ApiController
{
public IEnumerable<string> Post(List<string> val)
{
return val;
}
}
and for volley :
String tag_string_req = "req_login";
Map<String, String> params = new HashMap<>();
params.put("email", "S#b.Com");
params.put("username", "basheq");
JsonObjectRequest req = new JsonObjectRequest(Method.POST ,
AppConfig.URL_REGISTER, new JSONObject(params),new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
Log.d(TAG, "Login Response: " + jsonObject.toString());
}
}
, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(req, tag_string_req);
but i keep getting null in response and it look like the api doesn't parse the parameter .
what is wrong ?? , and is this the proper way to do it or is there a better way ??
The main problem was that i was setting list as a parameter which for some reason does not work
the solution was by wrapping the input parameter into a class and of course change the json structure to correspond to that

Send a DELETE Request using Volley (Android) to a REST Api with parameters?

How do I send a DELETE Request using Volley (Android) to a REST Api with parameters like access_token and username. I have tried almost everything on Internet but still I am getting a 400 error Message.
I have tried sending the same DELETE request using PostMan and it works perfectly fine.
Here is the Error:
E/Volley﹕ [1112] BasicNetwork.performRequest: Unexpected response code 400 for http://myserverip/messages/2
and Here is the Java code that I am using:
String URI = "http://myserverip/messages/2";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.DELETE,URI,null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(contextm,response.toString(),Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError 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("access_token", "access_token");
headers.put("username", "username");
return headers;
}
};
MyApp.getInstance().addToRequestQueue(request);
Might not be really useful but here is the working DELETE request preview from PostMan
DELETE /messages/1 HTTP/1.1
Host: serveripaddress
Cache-Control:no-cache
Content-Type: application/x-www-form-urlencoded
access_token=SPAVYaJ7ea7LzdeQYrBTsIRssuGbVpJI8G9XSV0n&username=whit3hawks
You can easily achieve this if you put the following instead of null in ... new JsonObjectRequest(Request.Method.DELETE,URI,null,new Response.Listener<JSONObject>() { ...
final JSONObject object = new JSONObject();
try {
object.put("access_token", "SPAVYaJ7ea7LzdeQYrBTsIRssuGbVpJI8G9XSV0n");
object.put("username", "whit3hawks");
} catch (Exception e) {
e.printStackTrace();
}
So your Request should look like this:
... new JsonObjectRequest(Request.Method.DELETE,URI,object,new Response.Listener<JSONObject>() { ...
You posted a long time ago, but maybe someone else will need this some time.
I am successfully sending headers in volley while using DELETE with this code:
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
return headers;
just tried it and works like a charm.
EDIT:
if you're using a Mac, try checking with Charles what exactly it is you are sending,
on a PC you can try fiddler.
also, error 400 means 'Bad Input', so the server is either getting more info then it should, or less then he expects.
and keep in mind that DELETE in Volley acts as a GET, make sure you are sending an empty body with the request.
hope that helped somehow.. happy coding

Android Volley access caching response data

I'm using Volley library to access my server data.Volley has inbuilt caching function.I tried to use that as follows.this out put "CACHED RESPONSE". but i don't know how to access the cached data.
void initHttpCall(){
RequestQueue queue = Volley.newRequestQueue(mcontext);
UOBRequest<RateData> myReq = new UOBRequest<RateData>(Method.GET,
Constants.GET_RATES,
RateData.class,
mlistner,
createMyReqErrorListener()){
#Override
public Map<String, String> getHeaders(){
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", getToken());
headers.put("Accept","application/json" );
return headers;
}
};
myReq.setShouldCache(true);
if(queue.getCache().get(Constants.GET_RATES)!=null){
System.out.println("CACHED RESPONSE");
}else{
queue.add(myReq);
}
}
}
This is my response listner and want to get RateData object here.
new Response.Listener<RateData>() {
#Override
public void onResponse(RateData rateData) {
setupCurrencyPager(rateData);
setLastUpdatedTime();
}
});
You misunderstood how Volley's caching system works. The beauty of it is that as a user of Volley, you are unaware of where the response is coming from.
When you add a new request to the RequestQueue, Volley checks if that request already has a cached response. If it does, and that response has not expired yet, it is returned immediately. Otherwise, it goes outside to the network, retrieves the response, caches it and returns it to you.
You don't need that last if statement, simply add it to the queue and Volley will take care of the rest.
try the following code.it will help you sure.
please create a request which you want to pass to server.
JSONObject request = new JSONObject();
request.put("user","user2");
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, url, request, new Response.Listener() {
#Override
public void onResponse(JSONObject response) {
// TODO Auto-generated method stub
Log.v("response:-"+response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(jsObjRequest);
}

Categories

Resources