VOLLEY / ANDROID : post request but parameters not received - java

I use volley Android library, I have create post request than send to my server :
JSONArray jsonRequest = new JSONArray();
for(MyLocation myLocation : ListLocation){
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("serial", myLocation.serial);
jsonObject.put("longitude", myLocation.longitude);
jsonObject.put("latitude", myLocation.latitude);
jsonObject.put("altitude", myLocation.altitude);
jsonObject.put("accuracy", myLocation.accuracy);
jsonObject.put("date", myLocation.date);
jsonRequest.put(jsonObject);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Request a string response from the provided URL.
JsonArrayRequest stringRequest = new JsonArrayRequest(url, jsonRequest,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
dabAcces.dropTable();
Log.d(TAG, "dropTable");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (row > MAX_REGISTER_GPS_DATA) {
Log.d(TAG, "deleteOldestRecord");
dabAcces.deleteOldestRecord();
}
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
}
But when I read my server information, I can see the post array it's empty, however when I verify jsonarray contents, I see variable to json format. Help me plz
[2015-08-13 09:30:39] local.INFO: POST
[2015-08-13 09:30:39] local.INFO: array ()
[2015-08-13 09:30:39] local.INFO: GET ------------------------------
[2015-08-13 09:30:39] local.INFO: array ()
[2015-08-13 09:30:39] local.INFO: SERVER ------------------------------
[2015-08-13 09:30:39] local.INFO: array (
'REDIRECT_STATUS' => '200',
'CONTENT_TYPE' => 'application/json; charset=utf-8',
'HTTP_USER_AGENT' => 'Dalvik/1.6.0 (Linux; U; Android 4.1.2; M17-G903-A Build/JZO54K)',
'HTTP_HOST' => 'geoloc.com',
'HTTP_CONNECTION' => 'Keep-Alive',
'HTTP_ACCEPT_ENCODING' => 'gzip',
'CONTENT_LENGTH' => '68921',
'PATH' => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
'SERVER_SIGNATURE' => '<address>Apache/2.4.10 (Ubuntu) Server at geoloc.com Port 80</address> 'SERVER_SIGNATURE' => '<address>Apache/2.4.10 (Ubuntu) Server at geoloc.com Port 80</address>

Looking at JsonArrayRequest in volley's source code
public JsonArrayRequest(String url, JSONArray jsonRequest, Listener<JSONArray> listener,
ErrorListener errorListener) {
this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,
listener, errorListener);
}
It means you need to pass a JsonArray not a JsonObject

Basically you cant use POST method for "JsonArrayRequest".
JsonArrayRequest class can be used to retrieve JSON array but not JSON object and only HTTP GET is supported as of now. As it supports only GET, so if you are to specify some querystring parameters then append those in the URL itself. The constructor does not accept request parameters.
If you want to send data in post method, you can use "JsonObjectRequest" OR "StringRequest".
Small example to send data in POST method using "StringRequest"
StringRequest strReq = new StringRequest(Request.Method.POST,
URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
Log.d(TAG, "Response: " + response.toString());
} catch (JSONException e) {
// JSON error
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("param1", "value1");
params.put("param2","value2");
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq);
you should override getParams() method to pass the data in POST method. Now you will get your data in the server end.

Related

Android Volley not being recognized as POST on server with php

I am using volley to sent post to my server. in my php inside insert.php i have code like this
if($_SERVER['REQUEST_METHOD'] == 'POST'){
//do all post functions
}
else{
//notofication that says its not post
}
This is my volley code in my android
String HttpUrl = "http://192.168.30.18/insert.php";
// Creating string request with post method
StringRequest stringRequest = new StringRequest(Request.Method.POST, HttpUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String ServerResponse) {
// Hiding the progress dialog after all task complete.
progressDialog.dismiss();
// Showing response message coming from server.
Toast.makeText(CreateAccountOrLoginActivity.this, ServerResponse, Toast.LENGTH_LONG).show();
Log.d("responseSuccess",ServerResponse);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
// Hiding the progress dialog after all task complete.
progressDialog.dismiss();
// Showing error message if something goes wrong.
Toast.makeText(CreateAccountOrLoginActivity.this, volleyError.toString(), Toast.LENGTH_LONG).show();
Log.d("responseFail",volleyError.toString());
}
}) {
#Override
protected Map<String, String> getParams() {
// Creating Map String Params.
Map<String, String> params = new HashMap<String, String>();
// Adding All values to Params.
params.put("title",title);
params.put("name", fname);
params.put("surname", sname);
return params;
}
};
// Creating RequestQueue.
RequestQueue requestQueue = Volley.newRequestQueue(CreateAccountOrLoginActivity.this);
// Adding the StringRequest object into requestQueue.
requestQueue.add(stringRequest);
The problem is after the android code is run, it returns what is in the else statement of the insert.php instead of what is in the if statement, meaning it is not being recognized as a post. How do i resolve it to make it run in the if statement

API returning error: "field cannot be empty"

I am currently trying to interface with the Tidal API and i'm having some trouble. Here is my code, I am using the Volley Library:
JSONObject pload = new JSONObject();
try {
pload.put("username", username);
pload.put("password", password);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, ENDPOINT, pload, response->{
Gson gson = new Gson();
JSONArray data = response.optJSONArray("data");
Log.d("RESPONSE", response.toString());
}, error -> {
String responseBody = null;
try {
responseBody = new String(error.networkResponse.data, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Log.d("ERROR", responseBody);
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("X-Tidal-Token", "q--------------------------k");
headers.put("Content-Type", "application/json");
return headers;
}
};
mqueue.add(request);
The LogCat:
D/REQUEST: body: {"username":"b-------#gmail.com","password":"p------"} ___ headers: {X-Tidal-Token=q---------------k, Content-Type=application/json} ___ request.tostring: [ ] https://api.tidalhifi.com/v1/login/username 0xcc20303d NORMAL null
E/Volley: [309] BasicNetwork.performRequest: Unexpected response code 400 for https://api.tidalhifi.com/v1/login/username
D/ERROR: {"status":400,"subStatus":1002,"userMessage":"password cannot be blank,username cannot be blank"}
As you can see the payload is not empty so i'm a bit confused. Tidal doesn't have an official API but there are some unofficial wrappers I have been using for reference, here are a few examples of used code:
Javascript:
request({
method: 'POST',
uri: '/login/username?token=kgsOOmYk3zShYrNP',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
form: {
username: authInfo.username,
password: authInfo.password,
}
Java:
var url = baseUrl.newBuilder()
.addPathSegment("login")
.addPathSegment("username")
.build();
var body = new FormBody.Builder()
.add("username", username)
.add("password", password)
.build();
var req = new Request.Builder()
.url(url)
.post(body)
.header(TOKEN_HEADER, token)
.build();
Java again:
HttpResponse<JsonNode> jsonResponse = restHelper.executeRequest(Unirest.post(API_URL + "login/username")
.header("X-Tidal-Token", "wdgaB1CilGA-S_s2")
.field("username", username)
.field("password", password));
If needed I can post the links to all the wrappers and provide a tidal token for testing (It's fairly easy to acquire you just need to sniff a packet from the tidal desktop app) . I've tried overriding getParams() but that didn't work. Any help is appreciated!
You're using the wrong format to send the request, You're using Json when you need a Url encoded format, the link for reference: Send form-urlencoded parameters in post request android volley
One Solution: A string request:
final String api = "http://api.url";
final StringRequest stringReq = new StringRequest(Request.Method.POST, api, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(getApplicationContext(), "Login Successful!", Toast.LENGTH_LONG).show();
//do other things with the received JSONObject
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Error!", Toast.LENGTH_LONG).show();
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> pars = new HashMap<String, String>();
pars.put("Content-Type", "application/x-www-form-urlencoded");
return pars;
}
#Override
public Map<String, String> getParams() throws AuthFailureError {
Map<String, String> pars = new HashMap<String, String>();
pars.put("Username", "usr");
pars.put("Password", "passwd");
pars.put("grant_type", "password");
return pars;
}
};
//add to the request queue
requestqueue.AddToRequestQueue(stringReq);

Sending a GET request with payload Volley

I want to make a GET request using Volley in Android Studio and in this request I want to include a body.
The problem is that when using the GET request, the body in the server is None (I am using Flask). On the other side, when using the POST method, the body reaches the server correctly. This is my code:
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
String url = Globals.WINGS_VEHICLES_URL;
JSONObject payload = new JSONObject();
try {
payload.put("user_id", Globals.USER_ID);
} catch (JSONException e) {
e.printStackTrace();
}
final String requestBody = payload.toString();
System.out.println(requestBody);
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
System.out.println(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}){
#Override
public String getBodyContentType() {
return "application/json";
}
#Override
public byte[] getBody() {
return requestBody.getBytes();
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(0, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(stringRequest);
Is this a Volley restriction, or am I doing something wrong? Assume that I am using a JSONObject as body, non empty.
please check this answer
HTTP GET with request body
and Use POST Http method to send Body!!

Android volley. Get data from the header of the HTTP response

I am making http requests to my REST server. As a response I get the JSON body. But I need to get also a parameter from the response header, as I keep the user token in it. I have looked at a lot of posts on Stack Overflow for similar questions, but I they don't seem to have helped me. I want to make a JSON request, and get the body and headers form the response. How can I do it? Here is my code:
Please don't mark the question as duplicate, as I have not found any example where I can retrieve both: the response header and the response body. For the existing questions, users get only the headers
JsonObjectRequest req = new JsonObjectRequest(AppConfig.URL_LOGIN, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println(response.toString());
hideDialog();
try {
JSONObject jObj = response;
String uid = jObj.getString("_id");
String name = jObj.getString("fullName");
String email = jObj.getString("email");
// Inserting row in users table
db.addUser(name, email, uid);
Toast.makeText(getApplicationContext(), "User successfully registered. Try login now!", Toast.LENGTH_LONG).show();
Intent intent = new Intent(
LoginActivity.this,
MainActivity.class);
startActivity(intent);
finish();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
String toastError = "Response code: " + networkResponse.statusCode;
Toast.makeText(getApplicationContext(),
toastError, Toast.LENGTH_LONG).show();
hideDialog();
}
});
You can't do that using JsonObjectRequest. You should extend the Request class and implement parseNetworkResponse() method which provides access to low-level NetworkResponse object. Downside is of course that you have to re-implement JSON parsing as well, but this is not really a big deal.
Something like:
public class HeaderAwareJsonRequest extends Request<Pair<JSONObject,Map>> {
protected Response.Listener<Pair<JSONObject,Map>> listener;
public HeaderAwareJsonRequest( int method, String url, Response.Listener<Pair<JSONObject,Map>> listener, Response.ErrorListener errorListener ) {
super( method, url, errorListener );
this.listener = listener;
}
#Override
protected Response<Pair<JSONObject,Map>> parseNetworkResponse( NetworkResponse response ) {
try{
String jsonString = new String( response.data, HttpHeaderParser.parseCharset( response.headers ) );
// pair contains the json body and headers
Pair pair = new Pair( new JSONObject( jsonString ), response.headers );
return Response.success( pair, HttpHeaderParser.parseCacheHeaders( response ) );
}catch( Exception e ){
return Response.error( new ParseError( e ) );
}
}
}
then in the calling code:
HeaderAwareJsonRequest req = new HeaderAwareJsonRequest(
Request.Method.GET,
AppConfig.URL_LOGIN,
new Response.Listener<Pair<JSONObject,Map>>() {
#Override
public void onResponse(Pair<JSONObject,Map> response) {
JSONObject jObj = response.first;
Map headers = response.second;
String someHeader = headers.get( "aaaaa" );
...
}
},
new Response.ErrorListener() {...}
);

Volley library dosent connect to server in some devices

in first i'm use Httpurlconnection and have same issue(Dosent find my Url in server in some devices and other device conncet easy) and i think bug e Httpurlconnection and i decide use Volley and same issue exist when use that
Error:
com.android.volley.VolleyError:java.lang.NullPointerException
Volley Code :
StringRequest postRequest = new StringRequest(Request.Method.POST, uri,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("HOOOO", response);
progressDialog.dismiss();
try {
JSONObject jsonobj = new JSONObject(response);
int success = Integer.parseInt(jsonobj.getString("success"));
String msg = jsonobj.getString("message");
check(Flag,success,msg,pass,email);
}catch (Exception e){
Snackbar snackbar1 = Snackbar.make(Mainlayout,e.toString(), Snackbar.LENGTH_LONG);
snackbar1.show();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Log.i("Error Respone", error.toString());
Snackbar snackbar1 = Snackbar.make(Mainlayout,error.toString(), Snackbar.LENGTH_LONG);
snackbar1.show();
}
}
) {
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<>();
if(Flag=="Insert") {
params.put("email", email);
params.put("fact", DeviseBrand);
params.put("model", DeviseModel);
}else if((Flag=="signin") ||(Flag=="update") ){
params.put("email", email);
}
// the POST parameters:
return params;
}
};
postRequest.setRetryPolicy(new DefaultRetryPolicy(
9000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(this).add(postRequest);
and my uri :
http://domain.com/App/Register.php
Post data and on server get with _Request[];
Volley is a very strong API, i don't think they could have such an issue, check your code maybe in some cases it doesn't initialize the object correctly.
I used Volley for more than 1 year and didn't had such issue.
1-check that you are using the latest release from this link.
2-put your code in question so we can check it with you, also the log could be helpful to trace the issue, also what is the device you are using ?

Categories