Volley服务器错误,网络响应为空。

10

每次我尝试使用Volley的POST方法,都会遇到服务器错误。我在getCause中得到null值,在getNetworkResponse.toString()中得到一些默认值。

如果我使用GET方法,这个工作正常(我从我的url获得响应)。

有人能帮忙解决吗?

    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: Error: com.android.volley.ServerError>>404>>[B@42b1e0d0>>null>>null

更新: 即使 URL 可访问(如果仅使用 GET 方法返回数据),networkResponse.statusCode 仍会显示为 404。如果在 POST 方法中删除 header 部分,情况仍然相同。

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

你有检查过 error.getMessage() 吗? - theapache64
是的,那也是 null。 - abdfahim
你有解决方案吗?我遇到了同样的错误,但在使用 Postman 进行测试时服务器正常响应。 - aya salama
8个回答

8
问题出在您的队列上。 将您的Volley代码更改为以下内容:
 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);  

把你的 PHP(Laravel)代码改为以下内容:
    $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);

// 在连接上增加可靠性。 request.setRetryPolicy(new DefaultRetryPolicy(10000, 1, 1.0f)); 这一行代码运作得非常好。感谢您给出的完美答案。 - Muhammad Ashfaq
请问您能否提供更多关于此事的信息?这神奇地解决了我所有的问题。POST请求已经被正确发送并且后端已经接收到,但是一个我无法访问的第三方API出现了故障。 - AliAvci

6
首先,尝试确保您的服务器正常工作。 您可以使用Postman(Chrome插件)或任何其他方法向URL发送POST请求并查看其响应。
确保服务器没有问题后,让我们解决Volley的问题。
当您使用POST方法时,JsonObjectRequest存在一些问题。就像这样:Volley JsonObjectRequest Post request not working
我建议您首先使用StringRequest,并覆盖getParams方法,就像以前一样。完成此任务后,您可以尝试编写自己的请求,这不是非常困难但非常有用。
我还建议在requestQueue.add(request)之前添加request.setShouldCache(false)。默认情况下,Volley将响应保存在其缓存中,这种行为可能会导致某些奇怪的问题。

谢谢,我会尝试一下。顺便说一句,我刚刚发现如果我用一个简单的文本文件替换PHP文件并将JSON数据放入其中(xxx.json),同样的代码就可以正常工作。这意味着什么特别的吗? - abdfahim
我对JsonObjectRequest的了解是,它在使用GET方法时效果很好,但当你使用POST方法时,getParams根本不会被调用。因此,我尝试编写自己的请求来解决这个问题。 - Kay Wu
实际上,我正在尝试通过将new JSONObject(jsonParams)作为JsonObjectRequest的第三个参数发送JSONObject到服务器。我也尝试使用GET方法进行操作,并且它可以工作。但是,由于jsonParams可能是一个非常大的数组,我不确定是否应该使用GET方法发送数据。 - abdfahim
好的,让我尝试使用GET方法...我可以得到响应,但在服务器端读取Volley发送的JSON(第三个参数)时遇到了困难。 - abdfahim
让我们在聊天中继续这个讨论 - Kay Wu
显示剩余5条评论

0

可能与您的运营商有关...

我使用Volley发送JasonObject时遇到了同样的问题。

我在9-10个设备上测试了我的应用程序,使用了两个不同的运营商。

其中一个运营商的请求返回一个错误,其中所有数据都为null或空白数据,而另一个运营商一切正常,我成功地从API中获取了响应。

我不知道运营商做了什么导致了这个问题......也许他们使用了某种防火墙来阻止发送JsonObject。


0

我尝试将响应显示为字符串,错误消失了。

在需要显示错误或使用它的任何地方使用response.toString()


0

嗯,我认为你可以先在logcat中打印出responseCode。


谢谢...我刚刚更新了我的帖子...networkResponse.statusCode = 404...看起来我的php文件有一些结构问题(url肯定是有效的) - abdfahim

0

在添加到队列之前添加以下代码:

request.setRetryPolicy(new DefaultRetryPolicy(0, -1, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

有时,在php完全执行之前,请求会超时。尝试使用此代码,可能会有所帮助。


0
在我的情况下,答案是重试策略设置。 我将超时值设为30秒,应该是30000,而不是30。

-1

尝试增加超时时间。我曾经遇到过同样的问题,请求超时是问题所在。


这是与 Kenneth的回答 相同的解决方案。 - Eric Aya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接