【问题标题】:Volley POST request, 400 errorVolley POST 请求,400 错误
【发布时间】:2014-05-19 10:00:58
【问题描述】:

这是我第一次使用 JSON,但我正在尝试使用 POST 请求。

我想向这个网站http://jsonblob.com/api发出一个POST请求

我的代码在我使用 asynctask + httppost 时有效

private static final String url = "http://jsonblob.com/api/jsonBlob";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new PostJsonTask().execute();
}

private class PostJsonTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... params) {
        try {
            HttpResponse response = post();
            Header s = response.getFirstHeader("Location");
            Log.d("PostJsonTask", s.getValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private HttpResponse post() throws Exception {
        // convert parameters into JSON object
        Map<String, String> params = new HashMap<String, String>();
        params.put("user", "Robby");
        params.put("pass", "zqdqzdqdqzd");
        JSONObject holder = new JSONObject(params);

        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(url);
        StringEntity se = new StringEntity(holder.toString());
        se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
        post.setHeader("Accept", "application/json");
        post.setHeader("Content-type", "application/json");
        post.setEntity(se);
        return client.execute(post);
    }
}

使用此代码,我可以成功获取 Location 参数。

但我想用 Volley 库来做这件事,我已经有了以下代码:

private static final String url = "http://jsonblob.com/api/jsonBlob";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    RequestQueue queue = Volley.newRequestQueue(this);

    StringRequest request = new StringRequest(Request.Method.POST, url, createResponseListener(), createErrorListener()) {
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Accept", "application/json");
            headers.put("Content-type", "application/json");

            return headers;
        }

        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("user", "Robby");
            params.put("pass", "zqdqzdqdqzd");

            return params;
        }

        @Override
        protected Response<String> parseNetworkResponse(
                NetworkResponse response) {
            Map<String, String> headers = response.headers;
            String location = headers.get("Location");
            Log.d("PostJsonTask", location);

            return super.parseNetworkResponse(response);
        }
    };

    queue.add(request);
}

private ErrorListener createErrorListener() {
    return new ErrorListener() {

        @Override
        public void onErrorResponse(VolleyError error) {
            error.printStackTrace();
        }
    };
}

private Listener<String> createResponseListener() {
    return new Listener<String>() {

        @Override
        public void onResponse(String response) {
            Log.d("PostJsonTask", response);
        }
    };
}

但这会返回代码为 400 的 VolleyError。我该如何解决这个问题?

【问题讨论】:

  • VolleyError 400 是什么意思?
  • 您在 new StringRequest() 中使用 createResponseListener() 作为参数,其中 createResponseListener 就足够了吗?

标签: android http-post android-volley


【解决方案1】:

不要尝试设置标头的内容类型,而是尝试为 bodyContentType 设置,而在 postman(web) 中,您也只是设置正文的内容类型

JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.POST,
        url, obj,
        new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                Log.d("Response", response.toString());

            }
        }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d("Error", error.toString());
                }
        })

    @Override
    public String getBodyContentType() {
        return "application/json";
    }
};

【讨论】:

  • 如果是自定义请求如何设置
【解决方案2】:

不要使用 getParams 覆盖。

相反,使用这些参数创建一个 JSON 并像在 JsonObjectRequest 中那样提供作为请求的主体(或者只使用 JsonObjectRequest 而不是 StringRequest),例如

JSONObject jsonObject = new JSONObject();
try {
    jsonObject.put("user", "Robby");
    jsonObject.put("pass", "zqdqzdqdqzd");
} catch (JSONException e) {
    // handle exception (not supposed to happen)
}

StringRequest request = new StringRequest(Request.Method.POST, url, createResponseListener(), createErrorListener()) {

    // your code without getParams

    @Override
    public byte[] getBody() {
        try {
            return jsonObject.toString.getBytes("utf-8");
        } catch (UnsupportedEncodingException uee) {
            // not supposed to happen
            return null;
        }
    }
}

【讨论】:

  • 有趣。您在 getParams 上使用 JSONObject 的原因是什么?是否可以传递其他参数类型,例如布尔值或整数?还是其他原因?
  • 根据我的经验,一些服务器对 JSON 主体的反应更好。刚刚提出了一个替代方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-28
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多