【问题标题】:Volley JsonObjectRequest Post parameters no longer workVolley JsonObjectRequest Post 参数不再起作用
【发布时间】:2015-06-09 04:19:51
【问题描述】:

我正在尝试在 Volley JsonObjectRequest 中发送 POST 参数。最初,它对我有用,按照官方代码所说的在 JsonObjectRequest 的构造函数中传递包含参数的 JSONObject。然后突然之间它停止工作,我没有对以前工作的代码进行任何更改。服务器不再识别正在发送的任何 POST 参数。这是我的代码:

RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://myserveraddress";

// POST parameters
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "test");

JSONObject jsonObj = new JSONObject(params);

// Request a json response from the provided URL
JsonObjectRequest jsonObjRequest = new JsonObjectRequest
        (Request.Method.POST, url, jsonObj, new Response.Listener<JSONObject>()
        {
            @Override
            public void onResponse(JSONObject response)
            {
                Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_SHORT).show();
            }
        },
        new Response.ErrorListener()
        {
            @Override
            public void onErrorResponse(VolleyError error)
            {
                Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
            }
        });

// Add the request to the RequestQueue.
queue.add(jsonObjRequest);

这是服务器上的简单测试器 PHP 代码:

$response = array("tag" => $_POST["tag"]);
echo json_encode($response);

我得到的回复是{"tag":null}
昨天,它运行良好,并回复{"tag":"test"}
我没有改变任何东西,但今天它不再起作用了。

在 Volley 源代码构造函数 javadoc 中,它说您可以在构造函数中传递 JSONObject 以在“@param jsonRequest”处发送 post 参数: https://android.googlesource.com/platform/frameworks/volley/+/master/src/main/java/com/android/volley/toolbox/JsonObjectRequest.java

/**
* 创建一个新请求。
* @param method 要使用的 HTTP 方法
* @param url 获取 JSON 的 URL
* @param jsonRequest 与请求一起发布的 {@link JSONObject}。允许为空并且
*       表示不会随请求一起发布任何参数。

我已阅读其他类似问题的帖子,但解决方案对我不起作用:

Volley JsonObjectRequest Post request not working

Volley Post JsonObjectRequest ignoring parameters while using getHeader and getParams

Volley not sending a post request with parameters.

我尝试将 JsonObjectRequest 构造函数中的 JSONObject 设置为 null,然后覆盖并设置“getParams()”、“getBody()”和“getPostParams()”方法中的参数,但这些都没有覆盖对我有用。另一个建议是使用一个额外的帮助类,它基本上创建了一个自定义请求,但是这个修复对于我的需要来说有点太复杂了。如果归根结底,我会做任何事情来使它工作,但我希望有一个简单的原因来解释为什么我的代码 工作,然后只是停止,也是一个简单的解决方案。

【问题讨论】:

  • 你找到解决办法了吗?
  • @Dory 是的,我确实找到了一个简单的解决方案。它没有解决 JsonObjectRequest 的问题,我只是完全放弃了 JsonObjectRequest,因为解决方案是改用 Volley 的 StringRequest。在下面查看我的答案,看看我做了什么。

标签: android post android-volley jsonobject


【解决方案1】:

您只需从参数的 HashMap 中创建一个 JSONObject:

String url = "https://www.youraddress.com/";

Map<String, String> params = new HashMap();
params.put("first_param", 1);
params.put("second_param", 2);

JSONObject parameters = new JSONObject(params);

JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.POST, url, parameters, new Response.Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject response) {
        //TODO: handle success
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        error.printStackTrace();
        //TODO: handle failure
    }
});

Volley.newRequestQueue(this).add(jsonRequest);

【讨论】:

  • 正确。这正是我所做的。请查看我发布的示例代码。起初它工作,但突然停止工作。但是,我一直使用 StringRequest 作为我的解决方案,此后没有遇到任何问题。
  • 我有个疑问,这里的方法名在哪里?
  • 这里没有方法,所以你不会看到任何方法名称 :p 这只是一些你可以放在你自己方法中的代码;)
【解决方案2】:

我最终改用 Volley 的 StringRequest,因为我花费了太多宝贵的时间来尝试使 JsonObjectRequest 工作。

RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://myserveraddress";

StringRequest strRequest = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>()
                {
                    @Override
                    public void onResponse(String response)
                    {
                        Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error)
                    {
                        Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
                    }
                })
        {
            @Override
            protected Map<String, String> getParams()
            {
                Map<String, String> params = new HashMap<String, String>();
                params.put("tag", "test");
                return params;
            }
        };

queue.add(strRequest);

这对我有用。它和 JsonObjectRequest 一样简单,但是使用了 String。

【讨论】:

  • 它在 android 5.1.1 上得到一个错误响应,虽然在 android 4.2 上工作
  • 收到错误 BasicNetwork.performRequest: Unexpected response code 500 for
  • @Joshua C. 这节省了我数小时无休止的搜索。知道为什么 JSONObjectRequest 不起作用吗?
  • @sidiabale 像你自己和 Joshua C。我想使用 JSONObjectRequest 来利用隐式 JSON 解析。令人难以置信的是,如果使用此类类型,则 POST 的参数以 JSON 格式发送。通常,无法控制服务器用于 POST 的格式。因此,如果无法自定义此行为,JSONObjectRequest 几乎毫无用处。
  • 这很好用,但是如果你想发送一个 JSONArray 的对象呢?
【解决方案3】:

我也遇到过类似的问题,但是我发现问题不在客户端,而是在服务器端。当您发送JsonObject 时,您需要像这样(在服务器端)获取 POST 对象:

在 PHP 中:

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

【讨论】:

  • 解决了我的问题(即使我在其他地方找到了它)
  • 谢谢。我认为这是 OPs 问题的答案。
  • 谢谢。不幸的是,这是真正的答案,与 JSONObjectRequest 无关
  • 你能解释一下吗?你有php的示例代码吗?
  • 应该代替php中的isset函数吗?
【解决方案4】:

您可以使用 StringRequest 执行与 JsonObjectRequest 相同的操作,同时仍然能够轻松发送 POST 参数。您唯一需要做的就是从您获得的请求字符串中创建一个 JsonObject,然后您可以从那里继续,就好像它是 JsonObjectRequest。

StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            //Creating JsonObject from response String
                            JSONObject jsonObject= new JSONObject(response.toString());
                            //extracting json array from response string
                            JSONArray jsonArray = jsonObject.getJSONArray("arrname");
                            JSONObject jsonRow = jsonArray.getJSONObject(0);
                            //get value from jsonRow
                            String resultStr = jsonRow.getString("result");
                        } catch (JSONException e) {

                        }

                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                }){
                    @Override
                    protected Map<String, String> getParams() throws AuthFailureError {
                        Map<String,String> parameters = new HashMap<String,String>();
                        parameters.put("parameter",param);

                        return parameters;
                    }

                };
                requestQueue.add(stringRequest);

【讨论】:

    【解决方案5】:

    使用 here 提到的 CustomJsonObjectRequest 帮助器类。

    并像这样实现 -

    CustomJsonObjectRequest request = new CustomJsonObjectRequest(Method.POST, URL, null, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            Toast.makeText(getActivity(), response.toString(), Toast.LENGTH_SHORT).show();
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(getActivity(), "Error.", Toast.LENGTH_SHORT).show();
        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("id", id);
            params.put("password", password);
            return params;
        }
    };
    VolleySingleton.getInstance().addToRequestQueue(request);
    

    【讨论】:

    • 是的,但是为什么 JsonObjectRequest 也使用 JSON 来创建 HTTP POST 请求的主体?并且考虑到正文通常以纯文本形式发送,服务器是否应该始终解码该正文以搜索可选的 JSON 内容?令人困惑...
    【解决方案6】:

    使用 JSONObject 对象发送参数意味着参数将在 HTTP POST 请求正文中为 JSON 格式:

    Map<String, String> params = new HashMap<String, String>();
    params.put("tag", "test");
    params.put("tag2", "test2");
    JSONObject jsonObj = new JSONObject(params);
    

    将创建此 JSON 对象并将其插入到 HTTP POST 请求的正文中:

    {"tag":"test","tag2":"test2"}
    

    然后服务器必须解码 JSON 以理解这些 POST 参数。

    但通常 HTTP POST 参数写在正文中,如:

    tag=test&tag2=test2
    

    但现在的问题是为什么 Volley 以这种方式设置?

    按照标准,读取 HTTP POST 方法的服务器应始终尝试以 JSON 格式(纯文本除外)读取参数,因此未完成的服务器是坏服务器?

    或者,一个带有 JSON 参数的 HTTP POST 正文不是服务器通常想要的?

    【讨论】:

      【解决方案7】:

      可能会帮助某人并节省您一些思考时间。 我有一个类似的问题,服务器代码正在寻找 Content-Type 标头。它是这样做的:

      if($request->headers->content_type == 'application/json' ){ //Parse JSON... }
      

      但是 Volley 发送的标题是这样的:

      'application/json; charset?utf-8'
      

      把服务器代码改成这样就行了:

      if( strpos($request->headers->content_type, 'application/json') ){ //Parse JSON... 
      

      【讨论】:

        【解决方案8】:

        我有类似的问题。但是我发现问题不在服务器端,而是缓存的问题。您必须清除 RequestQueue 缓存。

        RequestQueue requestQueue1 = Volley.newRequestQueue(context);
        requestQueue1.getCache().clear();
        

        【讨论】:

        【解决方案9】:

        你可以这样做:

        CustomRequest request = new CustomRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
        
                @Override
                public void onResponse(JSONObject response) {
                   // Toast.makeText(SignActivity.this, response.toString(), Toast.LENGTH_SHORT).show();
        
                    Log.d("response",""+response.toString());
        
                    String status =  response.optString("StatusMessage");
                    String actionstatus = response.optString("ActionStatus");
                    Toast.makeText(SignActivity.this, ""+status, Toast.LENGTH_SHORT).show();
                    if(actionstatus.equals("Success"))
                    {
                        Intent i = new Intent(SignActivity.this, LoginActivity.class);
                        startActivity(i);
                        finish();
                    }
                    dismissProgress();
        
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Toast.makeText(SignActivity.this, "Error."+error.toString(), Toast.LENGTH_SHORT).show();
                    Log.d("response",""+error.toString());
                    dismissProgress();
                }
            }) {
                @Override
                public String getBodyContentType() {
                    return "application/x-www-form-urlencoded; charset=UTF-8";
                }
        
                @Override
                protected Map<String, String> getParams() throws AuthFailureError {
                    Map<String, String> params = new HashMap<String, String>();
                    params.put("Email", emailval);
                    params.put("PassWord", passwordval);
                    params.put("FirstName", firstnameval);
                    params.put("LastName", lastnameval);
                    params.put("Phone", phoneval);
                    return params;
                }
        
            };
            AppSingleton.getInstance(SignActivity.this.getApplicationContext()).addToRequestQueue(request, REQUEST_TAG);
        

        根据以下链接的自定义请求 Volley JsonObjectRequest Post request not working

        【讨论】:

          【解决方案10】:

          确实有效。
          我使用以下方法解析了 json 对象响应:- 像魅力一样工作。

          String  tag_string_req = "string_req";
                  Map<String, String> params = new HashMap<String, String>();
                  params.put("user_id","CMD0005");
          
                  JSONObject jsonObj = new JSONObject(params);
          String url="" //your link
                  JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
                          url, jsonObj, new Response.Listener<JSONObject>() {
          
                      @Override
                      public void onResponse(JSONObject response) {
                          Log.d("responce", response.toString());
          
                          try {
                              // Parsing json object response
                              // response will be a json object
                              String userbalance = response.getString("userbalance");
          Log.d("userbalance",userbalance);
                              String walletbalance = response.getString("walletbalance");
                              Log.d("walletbalance",walletbalance);
          
                          } catch (JSONException e) {
                              e.printStackTrace();
                              Toast.makeText(getApplicationContext(),
                                      "Error: " + e.getMessage(),
                                      Toast.LENGTH_LONG).show();
                          }
          
                      }
                  }, new Response.ErrorListener() {
          
                      @Override
                      public void onErrorResponse(VolleyError error) {
                          Toast.makeText(getApplicationContext(),
                                  error.getMessage(), Toast.LENGTH_SHORT).show();
          
                      }
                  });
          
                  AppControllerVolley.getInstance().addToRequestQueue(jsonObjReq, tag_string_req);
          

          祝你好运! 晚安!

          【讨论】:

            【解决方案11】:

            它对我有用,可以尝试使用 Volley 调用 Json 类型的请求和响应。

              public void callLogin(String sMethodToCall, String sUserId, String sPass) {
                        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
            
                        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
                                Request.Method.POST, ConstantValues.ROOT_URL_LOCAL + sMethodToCall.toString().trim(), addJsonParams(sUserId, sPass),
                //                JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, object,
                                new Response.Listener<JSONObject>() {
                                    @Override
                                    public void onResponse(JSONObject response) {
                                        Log.d("onResponse", response.toString());
                                        Toast.makeText(VolleyMethods.this, response.toString(), Toast.LENGTH_LONG).show(); // Test
            
                                        parseResponse(response);
                //                        msgResponse.setText(response.toString());
                //                        hideProgressDialog();
                                    }
                                },
                                new Response.ErrorListener() {
            
                                    @Override
                                    public void onErrorResponse(VolleyError error) {
                                        VolleyLog.d("onErrorResponse", "Error: " + error.getMessage());
                                        Toast.makeText(VolleyMethods.this, error.toString(), Toast.LENGTH_LONG).show();
                //                hideProgressDialog();
                                    }
                                }) {
            
                            /**
                             * Passing some request headers
                             */
                            @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(jsonObjectRequest);
                    }
            
                    public JSONObject addJsonParams(String sUserId, String sPass) {
                        JSONObject jsonobject = new JSONObject();
                        try {
                //            {"id":,"login":"secretary","password":"password"}
            
                            ///***//
                            Log.d("addJsonParams", "addJsonParams");
            
                //            JSONObject jsonobject = new JSONObject();
            
                //            JSONObject jsonobject_one = new JSONObject();
                //
                //            jsonobject_one.put("type", "event_and_offer");
                //            jsonobject_one.put("devicetype", "I");
                //
                //            JSONObject jsonobject_TWO = new JSONObject();
                //            jsonobject_TWO.put("value", "event");
                //            JSONObject jsonobject = new JSONObject();
                //
                //            jsonobject.put("requestinfo", jsonobject_TWO);
                //            jsonobject.put("request", jsonobject_one);
            
                            jsonobject.put("id", "");
                            jsonobject.put("login", sUserId); // sUserId
                            jsonobject.put("password", sPass); // sPass
            
            
                //            js.put("data", jsonobject.toString());
            
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
            
                        return jsonobject;
                    }
            
                    public void parseResponse(JSONObject response) {
            
                        Boolean bIsSuccess = false; // Write according to your logic this is demo.
                        try {
                            JSONObject jObject = new JSONObject(String.valueOf(response));
                            bIsSuccess = jObject.getBoolean("success");
            
            
                        } catch (JSONException e) {
                            e.printStackTrace();
                            Toast.makeText(VolleyMethods.this, "" + e.toString(), Toast.LENGTH_LONG).show(); // Test
                        }
            
                    }
            

            【讨论】:

              【解决方案12】:

              希望派对还不算太晚: 问题出在服务器端。如果您使用的是 PHP,请在您的 php api 文件顶部添加以下行(包含后)

              $inputJSON = file_get_contents('php://input');
              if(get_magic_quotes_gpc())
              {
                  $param = stripslashes($inputJSON);
              }
              else
              {
                  $param = $inputJSON;
              }
              
              $input = json_decode($param, TRUE);
              

              然后检索您的值

              $tag= $input['tag'];
              

              【讨论】:

                【解决方案13】:

                ...最初,它对我有用 ....然后突然停止工作,我没有做任何更改 代码

                如果您没有对以前工作的代码进行任何更改,那么我建议检查其他参数,例如 URL ,因为如果您使用自己的计算机作为服务器,IP 地址可能会发生变化!

                【讨论】:

                • 请尝试更好地格式化您的问题。例如使用引号。
                猜你喜欢
                • 2013-11-19
                • 2021-06-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-01-26
                • 1970-01-01
                相关资源
                最近更新 更多