首页 文章

Volley JsonObjectRequest Post参数不再有效

提问于
浏览
26

我正在尝试在Volley JsonObjectRequest中发送POST参数 . 最初,对于我来说,遵循官方代码所说的传递包含JsonObjectRequest的构造函数中的参数的JSONObject的方式为 it was working . 然后它突然停止工作,我没有对以前工作的代码进行任何更改 . 服务器不再识别正在发送任何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方法HTTP方法使用 @param url URL从* @param jsonRequest A {@link JSONObject}获取JSON以发布请求 . 允许空值,*表示不会随请求一起发布参数 .

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

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()"方法中的参数,但这些覆盖都没有对我有效 . 另一个建议是使用一个基本上创建自定义请求的辅助类,但该修复对我的需求来说有点过于复杂 . 如果它归结为它我会做任何事情来使它工作,但我希望有一个简单的原因,为什么我的代码 was 工作,然后只是 stopped ,也是一个简单的解决方案 .

11 回答

  • 1

    您可以使用StringRequest执行与JsonObjectRequest相同的操作,同时仍然可以轻松发送POST参数 . 你唯一要做的就是从你得到的请求String中创建一个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);
    
  • 1

    你可以这样做:

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

    根据CustomRequest下面的链接Volley JsonObjectRequest Post request not working

  • 32

    使用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主体通常不是服务器想要的?

  • 1

    可以帮助别人并节省你一些时间思考 . 我遇到了类似的问题,服务器代码正在寻找Content-Type标头 . 它是这样做的:

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

    但是Volley正在发送这样的 Headers :

    'application/json; charset?utf-8'
    

    将服务器代码更改为此可以解决问题:

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

    您只需从参数的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.GET, 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);
    
  • 9

    它确实有效 .
    我使用以下方法解析了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);
    

    祝好运!晚安!

  • 1

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

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

    我最终使用了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 .

  • 32

    “...最初,它正在为我工作......然后它突然停止工作并且 I haven't made any changes 代码”

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

  • 0

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

    在PHP中:

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

    使用提到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);
    

相关问题