首页 文章

Android Volley - BasicNetwork.performRequest:意外的响应代码400

提问于
浏览
21

Problem statement:

我试图访问一个REST API,它将使用Volley返回各种HTTP状态代码(400,403,200等)的JSON对象 .

对于200以外的任何HTTP状态,似乎“意外响应代码400”是一个问题 . 有没有人有办法绕过这个'错误'?

Code:

protected void getLogin() {   
    final String mURL = "https://somesite.com/api/login";

    EditText username = (EditText) findViewById(R.id.username);
    EditText password = (EditText) findViewById(R.id.password);

    // Post params to be sent to the server
    HashMap<String, String> params = new HashMap<String, String>();
    params.put("username", username.getText().toString());
    params.put("password", password.getText().toString());

    JsonObjectRequest req = new JsonObjectRequest(mURL, new JSONObject(
            params), new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {

            try {
                JSONObject obj = response
                        .getJSONObject("some_json_obj");

                Log.w("myApp",
                        "status code..." + obj.getString("name"));

                // VolleyLog.v("Response:%n %s", response.toString(4));

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.w("error in response", "Error: " + error.getMessage());
        }
    });

    // add the request object to the queue to be executed
    AppController.getInstance().addToRequestQueue(req);
}

8 回答

  • 0

    我所做的是在我的网址上添加一个额外的'/',例如:

    String url = "http://www.google.com"
    

    String url = "http://www.google.com/"
    
  • 35

    在不更改 Volley 源代码的情况下执行此操作的一种方法是检查 VolleyError 中的响应数据并自行解析 .

    f605da3 commit开始, Volley 会抛出包含原始网络响应的ServerError exception .

    因此,您可以在错误侦听器中执行与此类似的操作:

    /* import com.android.volley.toolbox.HttpHeaderParser; */
    public void onErrorResponse(VolleyError error) {
    
        // As of f605da3 the following should work
        NetworkResponse response = error.networkResponse;
        if (error instanceof ServerError && response != null) {
            try {
                String res = new String(response.data,
                           HttpHeaderParser.parseCharset(response.headers, "utf-8"));
                // Now you can use any deserializer to make sense of data
                JSONObject obj = new JSONObject(res);
            } catch (UnsupportedEncodingException e1) {
                // Couldn't properly decode data to string
                e1.printStackTrace();
            } catch (JSONException e2) {
                // returned data is not JSONObject?
                e2.printStackTrace();
            }
        }
    }
    

    对于将来,如果 Volley 发生更改,可以按照上述方法进行操作,您需要检查服务器发送的原始数据 VolleyError 并进行解析 .

    我希望他们实现source file中提到的 TODO .

  • 7
    @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;
    }
    

    您需要将Content-Type添加到 Headers 中 .

  • 0

    我也得到了相同的错误,但在我的情况下,我用空格调用 url .

    然后,我通过解析如下修复它 .

    String url = "Your URL Link";
    
    url = url.replaceAll(" ", "%20");
    
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                                new com.android.volley.Response.Listener<String>() {
                                    @Override
                                    public void onResponse(String response) {
                                    ...
                                    ...
                                    ...
    
  • 13

    试试这个 ...

    StringRequest sr = new StringRequest(type,url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
    
                // valid response
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // error
            }
        }){
    
    @Override
        protected Map<String,String> getParams(){
            Map<String,String> params = new HashMap<String, String>();
                params.put("username", username);
                params.put("password", password);
                params.put("grant_type", "password");
            return params;
        }
    
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String,String> params = new HashMap<String, String>();
            // Removed this line if you dont need it or Use application/json
            // params.put("Content-Type", "application/x-www-form-urlencoded");
            return params;
        }
    
  • 2

    你的意思是想获得状态代码?

    VolleyError 的成员变量类型为 NetworkResponse ,它是公共的 .

    您可以访问 error.networkResponse.statusCode 以获取http错误代码 .

    我希望它对你有所帮助 .

  • 1

    在我的情况下,我没有写入reg_url:8080 . String reg_url =“http://192.168.29.163:8080/register.php”;

  • 9

    只是为了更新所有,经过一些审议后,我决定使用Async Http Client来解决我之前的问题 . 该库允许更清晰的方法(对我来说)操纵HTTP响应,尤其是在所有场景/ HTTP状态中返回JSON对象的情况下 .

    protected void getLogin() {
    
        EditText username = (EditText) findViewById(R.id.username); 
        EditText password = (EditText) findViewById(R.id.password); 
    
        RequestParams params = new RequestParams();
        params.put("username", username.getText().toString());
        params.put("password", password.getText().toString());
    
        RestClient.post(getHost() + "api/v1/auth/login", params,
                new JsonHttpResponseHandler() {
    
            @Override
            public void onSuccess(int statusCode, Header[] headers,
                    JSONObject response) {
    
                try {
    
                    //process JSONObject obj 
                    Log.w("myapp","success status code..." + statusCode);
    
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
            @Override
            public void onFailure(int statusCode, Header[] headers,
                    Throwable throwable, JSONObject errorResponse) {
                Log.w("myapp", "failure status code..." + statusCode);
    
    
                try {
                    //process JSONObject obj
                    Log.w("myapp", "error ..."  + errorResponse.getString("message").toString());
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }
    

相关问题