Sto usando HttpUrlConnection
per fare richieste di rete dalla mia applicazione Android. Tutto funziona bene tranne una cosa, 401. Ogni volta che il server restituisce la risposta con il codice di stato 401, la mia app genera IOException
con un messaggio che indica, "no authentication challenge found"
. Dopo averlo fatto su Google, non ho trovato una soluzione singola, ma solo una soluzione alternativa (gestirla usando try/catch, assumendo una risposta 401).Come ottenere 401 risposta senza gestirlo utilizzando try/catch in Android
Ecco il frammento di codice:
public Bundle request(String action, Bundle params, String cookie) throws FileNotFoundException, MalformedURLException, SocketTimeoutException,
IOException {
OutputStream os;
String url = baseUrl + action;
Log.d(TAG, url);
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setConnectTimeout(30 * 1000);
conn.setReadTimeout(30 * 1000);
conn.setRequestProperty("User-Agent", System.getProperties().getProperty("http.agent") + "AndroidNative");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setDoOutput(true);
conn.setDoInput(true);
if (cookie != null) {
conn.setRequestProperty("Cookie", cookie);
}
if (params != null) {
os = conn.getOutputStream();
os.write(("--" + boundary + endLine).getBytes());
os.write((encodePostBody(params, boundary)).getBytes());
os.write((endLine + "--" + boundary + endLine).getBytes());
uploadFile(params, os);
os.flush();
os.close();
}
conn.connect();
Bundle response = new Bundle();
try {
response.putInt("response_code", conn.getResponseCode());
Log.d(TAG, conn.getResponseCode() + "");
response.putString("json_response", read(conn.getInputStream()));
List<String> responseCookie = conn.getHeaderFields().get("set-cookie");
// Log.d(TAG, responseCookie.get(responseCookie.size() - 1));
response.putString("cookie", responseCookie.get(responseCookie.size() - 1));
} catch (SocketTimeoutException e) {
throw new SocketTimeoutException(e.getLocalizedMessage());
} catch (FileNotFoundException e) {
throw new FileNotFoundException(e.getLocalizedMessage());
} catch (IOException e) {
e.printStackTrace();
response.putInt("response_code", HttpURLConnection.HTTP_UNAUTHORIZED);
response.putString("json_response", read(conn.getErrorStream()));
}
// debug
Map<String, List<String>> map = conn.getHeaderFields();
for (String key : map.keySet()) {
List<String> values = map.get(key);
for (String value : values) {
Log.d(key, value);
}
}
conn.disconnect();
return response;
}
voglio davvero sapere, perché è gettato questa eccezione? Che cosa significa la verifica dell'autenticazione? Come fornire una sfida di autenticazione? che cambiamento devo fare nel mio codice per superare questa situazione?
Si prega di illuminarmi .. :)
Direi significa che il server ha risposto con un codice di errore 401, ma omette l'intestazione 'WWW-Authenticate' che descrive la richiesta di autenticazione. Il server – Jens
ha l'intestazione 'WWW-Authenticate', ma sto ancora ricevendo questo errore. – jtanveer
Mi sono solo imbattuto in questo, e inoltre non riesco a capire come ottenere questo codice di risposta senza dover presumere che sia un 401 dopo aver catturato IOException (poiché 'getResponseCode()' stesso genererà la stessa IOException di 'connect()/getInputStream()/getOutputStream() '). Da stacktrace sembra 'org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.processAuthHeader (HttpURLConnectionImpl.java:1153)' è responsabile per lanciare l'eccezione sulla catena (anche se non ho potuto immergersi ulteriormente). –