2014-11-07 3 views
16

dichiarazione del problema:Android Volley - BasicNetwork.performRequest: codice di risposta imprevisto 400

Sto cercando di accedere a un API REST che restituirà un oggetto JSON per diversi codici di stato HTTP (400, 403, 200, ecc) usando Volley.

Per qualsiasi stato HTTP diverso da 200, sembra che "Il codice di risposta imprevisto 400" sia un problema. Qualcuno ha un modo per aggirare questo 'errore'?

Codice:

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

Ho avuto il carattere "é" nella mia stringa di query. Ho lavorato dopo aver codificato tutti i miei parametri. – Kiran

risposta

1

Solo per aggiornare tutto, dopo alcune discussioni, ho deciso di utilizzare il client Async Http per risolvere il mio problema precedente. La libreria consente un approccio più pulito (per me) per manipolare le risposte HTTP soprattutto nei casi in cui gli oggetti JSON vengono restituiti in tutti gli scenari/stati HTTP.

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

Vuoi dire che vogliono ottenere i codici di stato?

VolleyError ha un tipo variabile membro di NetworkResponse ed è pubblico.

È possibile accedere a error.networkResponse.statusCode per il codice di errore http.

Spero sia utile per voi.

5

Prova questo ...

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; 
    } 
+0

che è stato grande grazie – HPbyP

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

È necessario aggiungere Content-Type per l'intestazione.

+0

invio richiesta di ottenere. api funziona bene ma ottiene BasicNetwork.performRequest: codice di risposta inattesa 500. – JosephM

+0

@HemsLodha 500 - Errore interno server "Un messaggio di errore generico, dato quando si verificava una condizione imprevista e nessun messaggio specifico è adatto" È un problema sul server. – Malder

+0

Si è verificato un errore simile, ma il mio era "Codice di risposta inaspettato 415". Avevo l'applicazione Content-Type/JSON, ma dopo aver aggiunto charset = utf-8, il problema è scomparso. –

23

Un modo di fare questo senza cambiare Volley 's codice sorgente è di controllare per i dati di risposta nel VolleyError e analizzare la vostra auto.

A partire da f605da3 commit, Volley genera un ServerError exception che contiene la risposta di rete non elaborata.

Così si può fare qualcosa di simile a questo nel vostro ascoltatore di errore:

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

Per il futuro, se Volley modifiche, si può seguire l'approccio di cui sopra in cui è necessario controllare la VolleyError per i dati grezzi che è stato inviato dal server e analizzarlo.

Spero che implementino quello TODO menzionato nello source file.

2

Anche io ho avuto lo stesso errore ma nel mio caso stavo chiamando url con spazi vuoti.

Quindi, l'ho risolto analizzando come di seguito.

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) { 
           ... 
           ... 
           ... 
+1

Grazie mille !! Questo risolve il mio problema in Android 4.4.2 – sebasira