Reputation: 3825
This seems like an already asked question, but I have tried almost every question on stackoverflow.
I am unable to receive response from server using volley. The error inside onErrorRespose() is:
com.android.volley.ParseError: org.json.JSONException: Value <br of type java.lang.String cannot be converted to JSONObject
The GET method php looks like:
So the params must look like:
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put(KEY_USERNAME, "loyal_customer");
params.put(KEY_PASSWORD, "custumerXYZ");
params.put(KEY_INFO, "merchant_names");
return params;
}
Where the keys in global are defined as:
public static final String KEY_USERNAME="username";
public static final String KEY_PASSWORD="password";
public static final String client_side_php="https://vidorvistrom.000webhostapp.com/client_access.php";
public static final String KEY_INFO="info_req";
And here is my makeRequest() method which I call inside the onClick() listener:
public void makeRequest() {
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
final JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, client_side_php, null,
new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
Log.d("response: ", String.valueOf(response.getJSONObject("name")));// response.getString("name") also tried and name is the column name in the database which works fine with GET
} catch (JSONException e) {
Log.d("this: ",e.toString());
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put(KEY_USERNAME, "loyal_customer");
params.put(KEY_PASSWORD, "custumerXYZ");
params.put(KEY_INFO, "merchant_names");
return params;
}
};
requestQueue.add(jsObjRequest);
}
I am afraid that I am missing something. This is my first try on volley.
The application doesn't crash. It just don't do anything at all.
Php code:
<?php
$username=$_POST["username"];
$password=$_POST["password"];
$info_req=$_POST["info_req"];
if($info_req==""){
$string.="Error 404. Not Found";
$data[]=$string;
}
else{
$con=mysqli_connect(details hidden from public);
$string="";
$data=array();
if(!$con){
$string.="Connection Failed. Bad Access to database!";
$data[]=$string;
}
else{
$query="Select * from client_side_records where username='{$username}'";
$result=mysqli_query($con,$query);
$row=mysqli_fetch_assoc($result);
$pass_db=$row["password"];
if($pass_db==$password){
if($info_req=="merchant_names"){
$query="Select name, id from merchant_side_records";
$result=mysqli_query($con,$query);
while($row=mysqli_fetch_assoc($result)){
foreach($row as $key => $value) {
$data[$key] = $value;
}
}
}
}
else{
$string.="Login Failed";
$data[]=$string;
}
}
}
$data=json_encode($data);
echo $data;
?>
As suggested I tried using hurl.it to check if server is responding to post request, I seems fine:
POST https://vidorvistrom.000webhostapp.com/client_access.php
200 OK 36 bytes 480 ms
View Request View Response
HEADERS
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Tue, 25 Jul 2017 12:09:17 GMT
Server: awex
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Request-Id: 8edf2f8e9e53f138e700aef92d58045a
X-Xss-Protection: 1; mode=block
BODY view formatted
{"name":"Paan Singh Tomar","id":"1"}
Upvotes: 1
Views: 1176
Reputation: 3825
Okay, I have been researching on quite a few topics for an aw-while to find a solution for this one.
Exact problem: Bad json formation and false(not wrong!) parameters being passed.
Many answers I went through over SO and otherwise mostly suggested:
I want to bring a few things in notice and clearly state them all together for someone else suffering:
But before let me give an overview what was I doing initially
getBody()
or getParams()
methods by making a HashMap within them. Though above things look good but are jumbled pieces from here and there, and guess what, they do not belong to the same puzzle.
And now one thing I want to make real clear before moving forward:
Please read this if you don't already know before proceeding.
Now lets proceed further
If you use StringRequest
A typical StringRequest would look like
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
.
.
.
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
.
.
.
}
}){
.
.
.
};
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
requestQueue.add(stringRequest);
If we receive data using this way, then note a response is in form of a string. So as an obvious statement, php must echo a string.
You may collect that string and make a JSON object out of it. The string must look like this.
Override getParams() method to pass POST parameters
Then proceed in the normal way(manipulate that JSON object...)
If you use JsonArrayRequest
First thing, we are expecting a JSON array from php, so the php must echo JSON array(the one starting with square braces)
Second, passing POST params will not work in the usual overriding way. You have to make a map and add parameters to it. Then make a JSON object out of it and pass that object in the 3rd argument.
Something like:
Map<String, String> **params** = new HashMap<String, String>();
params.put(KEY_USERNAME, "loyal_customer");
params.put(KEY_PASSWORD, "custumerXYZ");
params.put(KEY_INFO, "merchant_names");
JSONObject parameters =new JSONObject(params);
public JsonArrayRequest(int method, String url, JSONObject **params**,
Listener<JSONArray> listener, ErrorListener errorListener)
And when we pass JSON object as post parameters, php receives a JSON instead of standard values in POST.
So you have to decode those post parameters like this:
$json = json_decode( file_get_contents('php://input') );
And then check for parameters like this:
if (isset($json->{'username'}) && isset($json->{'password'}) && isset($json->{'password'})) {
$username = $json->{'username'};
$password = $json->{'password'};
$info_req = $json->{'info_req'};
}
And then when you receive JSON array inside onRespose, iterate through it and manipulate its content.
If you use JsonObjectRequest
(This is somehow more intriguing for unknown reasons, at-least in my case!)
Again, we expect an object, not array!
And in the similar fashion we send parameters by a JSON object made of a map, just as in JsonArrayRequest
So this must imply the same thing that php is receiving JSON object as POST parameter and we must do the same as before(JsonArrayRequest) inside php.
Now after all these, a yet another important thing to note:
You must learn exactly how to make a JSON object or JSON array.
In my case(the working one) I went with the third way, receiving JSON object that contains a JSON array with all the necessary values in form of nested JSON objects.
Something like this:
{"Tag":[{"error":true},{"id":1,"name":"Vidor Vistrom"},{"id":2,"name":"Dealo Ell"}]}
You may want to see my implementation(php is security vulnerable though! but for public use, so don't be skeptical of public exposure):
Upvotes: 1
Reputation: 458
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
require_once("dbcon.php");
$response=array();
$response['error'] = false;
$response['merchants'] = array();
if (isset($_POST['username']) && isset($_POST['password']) && isset($_POST['info_req'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$info_req = $_POST['info_req'];
$con=mysqli_connect(details hidden from public);
if (!$con) {
$response['error'] = true;
$response['message'] = "Connection Failed. Bad Access to database!";
} else {
$query="SELECT * FROM client_side_records WHERE username = '{$username}'";
$result=mysqli_query($con,$query);
$row =mysqli_fetch_assoc($result);
$pass_db = $row["password"];
if($pass_db==$password){
if($info_req == "merchant_names"){
$query="SELECT name, id FROM merchant_side_records";
$result=mysqli_query($con,$query);
while($row=mysqli_fetch_assoc($result)){
$temp = array();
$temp['id'] = $row['id'];
$temp['name'] = $row['name'];
array_push($response['merchants'], $temp);
}
} else if($info_req == "merchant_details") {
$merchant_id = $_POST["merchant_id"];
$query="SELECT name, shop_name, address FROM merchant_side_records WHERE id='{$merchant_id}'";
$result=mysqli_query($con,$query);
while($row=mysqli_fetch_assoc($result)) {
$temp = array();
$temp['name'] = $row['name'];
$temp['shop_name'] = $row['shop_name'];
$temp['address'] = $row['address'];
array_push($response['merchants'], $temp);
}
}
} else {
$response['error'] = true;
$response['message'] = "Login failed";
}
}
} else {
$response['error'] = true;
$response['message'] = "404 not found...";
}
} else {
$response['error'] = true;
$response['message'] = "Please check method. it must be POST";
}
header("content-type:application/json");
echo json_encode($response);
?>
//output as shown below as jsonarray
{
"error": false
"merchants": [{
"id": 1,
"name": abc
},
{
"id": 1,
"name": xyz
}]
}
// change ur android response in volley
boolean error = response.getBoolean("error"));
if(!error) {
JsonArray jsonArray = response.getJSONArray("merchants"));
for(int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String name = jsonObject.getString("name");
}
}
Upvotes: 1
Reputation: 1087
Try override getBodyContentType
@Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
}
Upvotes: 0