wake-up-neo.com

Android Volley - BasicNetwork.performRequest: Unerwarteter Antwortcode 400

Problemstellung:

Ich versuche, auf eine REST - API zuzugreifen, die ein JSON-Objekt für verschiedene HTTP-Statuscodes (400, 403, 200 usw.) mit Volley zurückgibt.

Bei einem anderen HTTP-Status als 200 scheint der 'unerwartete Antwortcode 400' ein Problem zu sein. Hat jemand eine Möglichkeit, diesen "Fehler" zu umgehen?

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);
}
21
clearstake

Eine Möglichkeit, dies zu tun, ohne den Quellcode von Volley zu ändern, besteht darin, die Antwortdaten in der VolleyError zu überprüfen und selbst zu analysieren.

Ab f605da3 commit löst Volley eine ServerError-Ausnahme aus , die die unformatierte Netzwerkantwort enthält.

Sie können also in Ihrem Fehlerlistener etwas Ähnliches tun:

/* 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();
        }
    }
}

Wenn sich Volley ändert, können Sie in der Zukunft der obigen Vorgehensweise folgen, bei der Sie die VolleyError auf vom Server gesendete Rohdaten überprüfen und analysieren müssen.

Ich hoffe, dass sie die in der source-Datei erwähnte TODO implementieren .

33
listboss
@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;
}

Sie müssen dem Header Content-Type hinzufügen.

13
Tayseer

Ich hatte auch den gleichen Fehler, aber in meinem Fall rief ich url mit Leerzeichen an.

Dann reparierte ich es wie unten beschrieben.

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) {
                                ...
                                ...
                                ...
8
Rasool Mohamed

Versuche dies ...

 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;
    }
7
dhiku

Sie meinen, dass Sie Statuscodes erhalten möchten?

VolleyError hat einen Mitgliedervariablentyp NetworkResponse und ist öffentlich.

Sie können auf error.networkResponse.statusCode für den http-Fehlercode zugreifen.

Ich hoffe es ist hilfreich für dich.

2
AngelInKate

in meinem Fall schrieb ich nicht reg_url mit: 8080 . String reg_url = " http://192.168.29.163:8080/register.php ";

1
Manibala Sinha

veränderung

public static final String URL = " http: // api-Location ";

zu

public static final String URL = " https: // api-Location "

es ist passiert, weil ich 000webhostapp App verwende

0
tnfaid

Was ich getan habe, war ein zusätzliches "/" an meine URL anzufügen, z. :

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

zu 

String url = "http://www.google.com/"
0
tick t

Um alles zu aktualisieren, habe ich mich nach einigen Überlegungen entschieden, stattdessen den Async HTTP-Client zu verwenden, um mein früheres Problem zu lösen. Die Bibliothek ermöglicht einen saubereren Ansatz ( to me ) zur Bearbeitung von HTTP-Antworten, insbesondere in Fällen, in denen JSON-Objekte in allen Szenarien/HTTP-Status zurückgegeben werden.

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();
            }
        }
    });
}
0
clearstake