Volley JsonObjectRequest Post参数不再工作



我正试图在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/sellity/toolbox/JsonObjectRequest.java

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

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

Volley JsonObjectRequest Post请求不工作

Volley Post JsonObjectRequest在使用getHeader和getParams 时忽略参数

Volley没有发送带有参数的post请求。

我曾尝试将JsonObjectRequest构造函数中的JSONObject设置为null,然后重写并设置"getParams()"、"getBody()"one_answers"getPostParams(()"方法中的参数,但这些重写都不适用于我。另一个建议是使用一个额外的助手类,它基本上可以创建一个自定义请求,但这个修复对我的需求来说有点太复杂了。归根结底,我会尽一切努力让它发挥作用,但我希望有一个简单的原因来解释为什么我的代码工作的,然后只是停止,还有一个简单解决方案。

您只需要从参数的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);

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

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

在PHP中:

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

您可以使用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);

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

使用JSONObject对象发送参数意味着参数将在HTTPPOST请求体中采用JSON格式:

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

将创建这个JSON对象并将其插入HTTPPOST请求的主体中:

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

然后服务器必须对JSON进行解码才能理解这些POST参数。

但通常HTTPPOST参数在正文中写入,如:

tag=test&tag2=test2

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

根据标准,读取HTTPPOST方法的服务器应该始终尝试读取JSON中的参数(而不是纯文本),所以没有完成的服务器就是一个坏服务器?

或者,服务器通常不想要一个带有JSON参数的HTTPPOST主体?

可能会帮助他人并节省一些思考时间。我遇到了类似的问题,服务器代码正在查找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... 

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

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

您可以这样做:

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请求不起作用

它确实起作用
我使用以下内容解析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);

它对我有效。我可以尝试用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
            }
        }

希望聚会不要太迟:问题来自服务器端。如果您正在使用PHP,请在phpapi文件的顶部添加以下行(包含之后)

$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'];

使用GET代替POST来使用JsonObjectRequest

VolleySingleton.getInstance()
                .add(new StringRequest(Request.Method.POST, urlToTest, new Response.Listener<String>() {
                         @Override
                         public void onResponse(String response) {
                             // do stuff...
                         }
                     }, new Response.ErrorListener() {
                         @Override
                         public void onErrorResponse(VolleyError error) {
                             // exception
                         }
                     }) {
                         @Override
                         public String getBodyContentType() {
                             return "application/x-www-form-urlencoded; charset=UTF-8";
                         }
                         @Override
                         protected Map<String, String> getParams() {
                             return ServerApi.getRequiredParamsRequest(context);
                         }
                     }
                );

起初,它对我有效……然后它突然停止工作,我没有对进行任何更改代码

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

最新更新