凌空没有回应

No response from volley

这似乎是一个已经问过的问题,但我已经尝试了几乎所有关于 Whosebug 的问题。

我无法使用 volley 接收来自服务器的响应。 onErrorRespose() 里面的错误是:

com.android.volley.ParseError: org.json.JSONException: Value <br of type java.lang.String cannot be converted to JSONObject

因此参数必须如下所示:

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

其中全局键定义为:

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

这是我在 onClick() 侦听器中调用的 makeRequest() 方法:

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

恐怕我错过了什么。这是我第一次尝试排球。

应用程序没有崩溃。它根本不做任何事情。

Php代码:

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

?>

按照建议,我尝试使用 hurl.it 检查服务器是否响应 post 请求,我看起来很好:

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

尝试覆盖 getBodyContentType

@Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
                        }
<?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");
}
}

好吧,我已经研究了很多主题了一段时间,以找到解决这个问题的方法。

确切问题:错误的json 构造和错误(没有错!)传递的参数。

我在 SO 上经历了很多答案,其他大部分都是建议的:

  • 制作 StringRequest 而不是 JsonObjectRequest 或 JsonArrayRequest
  • 数据库中存储的值存在一些错误
  • 解析错误json

我想提几点注意事项,并为其他受苦的人清楚地说明它们:

但在让我概述一下我最初在做什么之前

  • 发出 JsonObjectRequest
  • 通过在其中创建一个 HashMap 来覆盖 getBody()getParams() 方法来传递参数。
  • 正在使用 $_POST["post-value"][=121 在 php 中检索 POST 参数=]
  • 任何方式从数据库中检索信息,然后将它们编码为json并回显它们。
  • 奇怪为什么一切都这么恶毒!

虽然上面的东西看起来不错但是到处都是乱七八糟的碎片,你猜怎么着,它们不属于同一个谜题。

现在我想在继续之前明确一件事:

  • JSON对象JSON数组
  • 有区别

如果您在继续之前还不知道,请阅读 this

现在让我们继续

  • 如果使用StringRequest

    典型的 StringRequest 看起来像

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

    如果我们使用这种方式接收数据,请注意响应是字符串形式的。因此,作为一个明显的陈述,php 必须回显一个字符串。

您可以收集该字符串并从中创建一个 JSON 对象。字符串必须类似于 this.

覆盖 getParams() 方法以传递 POST 个参数

然后以正常方式进行(操作那个JSON对象...)

  • 如果使用JsonArrayRequest

    首先,我们期待 php 的 JSON 数组,因此 php 必须回显 JSON 数组(以方括号开头的数组)

    其次,传递 POST 参数不会以通常的覆盖方式工作。您必须制作地图并向其添加参数。然后从中创建一个 JSON 对象并在第三个参数中传递该对象。

类似于:

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)

并且当我们将 JSON 对象作为 post 参数传递时,php 收到 JSON 而不是 POST 中的标准值。

所以你必须像这样解码那些 post 参数:

$json = json_decode( file_get_contents('php://input') );

然后像这样检查参数:

if (isset($json->{'username'}) && isset($json->{'password'}) && isset($json->{'password'})) {
    $username = $json->{'username'};
    $password = $json->{'password'};
    $info_req = $json->{'info_req'};
}

然后当您在 onRespose 中收到 JSON 数组时,遍历它并操作其内容。

  • 如果使用JsonObjectRequest

    (由于未知原因,这在某种程度上更有趣,至少在我看来是这样!)

    同样,我们需要一个对象,而不是数组!

    并且以类似的方式,我们通过由地图构成的 JSON 对象发送参数,就像在 JsonArrayRequest

    中一样

    所以这一定意味着 php 正在接收 JSON 对象作为 POST 参数,我们必须在 php 中执行与之前(JsonArrayRequest)相同的操作.

现在,在所有这些之后,还要注意另一件重要的事情:

  • 您必须准确了解如何制作 JSON 对象或 JSON 数组。

    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. 
    

像这样:

{"Tag":[{"error":true},{"id":1,"name":"Vidor Vistrom"},{"id":2,"name":"Dealo Ell"}]}

你可能想看看我的实现(虽然 php 存在安全漏洞!但是对于 public 使用,所以不要怀疑 public 曝光):