Comment obtenir le corps de la réponse à l'aide de HttpURLConnection, lorsqu'un code autre que 2xx est renvoyé?

95

J'ai un problème avec la récupération de la réponse Json au cas où le serveur renvoie une erreur. Voir les détails ci-dessous.

Comment j'exécute la demande

J'utilise java.net.HttpURLConnection. Je configure les propriétés de la requête, puis je fais:

conn = (HttpURLConnection) url.openConnection();

Après cela, lorsque la demande est réussie, j'obtiens la réponse Json:

br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
sb = new StringBuilder();
String output;
while ((output = br.readLine()) != null) {
  sb.append(output);
}
return sb.toString();

... et le problème est:

Je ne peux pas récupérer Json reçu lorsque le serveur renvoie une erreur comme 50x ou 40x ,. La ligne suivante lance IOException:

br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
// throws java.io.IOException: Server returned HTTP response code: 401 for URL: www.example.com

Le serveur envoie le corps à coup sûr, je le vois dans l'outil externe Burp Suite:

HTTP/1.1 401 Unauthorized

{"type":"AuthApiException","message":"AuthApiException","errors":[{"field":"email","message":"Invalid username and/or password."}]}

Je peux obtenir un message de réponse (c'est-à-dire "Erreur interne du serveur") et un code (c'est-à-dire "500") en utilisant les méthodes suivantes:

conn.getResponseMessage();
conn.getResponseCode();

Mais je ne peux pas récupérer le corps de la requête ... peut-être qu'il y a une méthode que je n'ai pas remarquée dans la bibliothèque?

kiedysktos
la source

Réponses:

132

Si le code de réponse n'est pas 200 ou 2xx, utilisez à la getErrorStream()place degetInputStream().

Marquis de Lorne
la source
2
dans mon cas, ayant un code de réponse 403, getErrorStream () renvoie null
Sip
68

Pour clarifier les choses, voici mon code de travail:

if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 399) {
    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
    br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
kiedysktos
la source
3
HttpURLConnection.getErrorStream()( sun.net.www.protocol.httpimplémentation) retourne à nullmoins responseCode >= 400, donc votre chèque pour 299 est probablement incorrect.
vladr
5
Si vous utilisez Java 8, vous pouvez obtenir la réponse sous forme de chaîne. String responseBody = br.lines().collect(Collectors.joining());
Lanil Marasinghe
1
La plage correcte est de 200 à 399, car 3xx est un état de «redirection», pas une erreur.
luca.vercelli
1

C'est un moyen facile d'obtenir une réponse réussie du serveur comme PHP echo sinon un message d'erreur.

BufferedReader br = null;
if (conn.getResponseCode() == 200) {
    br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String strCurrentLine;
        while ((strCurrentLine = br.readLine()) != null) {
               System.out.println(strCurrentLine);
        }
} else {
    br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
    String strCurrentLine;
        while ((strCurrentLine = br.readLine()) != null) {
               System.out.println(strCurrentLine);
        }
}
Sharhabeel Hamdan
la source