L'utilisation sécuritaire de HttpURLConnection
Lors de l'utilisation de HttpURLConnection ne l'InputStream doivent être fermés si nous ne faisons pas " get " et l'utiliser?
c'est à dire est-ce sûr?
HttpURLConnection conn = (HttpURLConnection) uri.getURI().toURL().openConnection();
conn.connect();
//check for content type I don't care about
if (conn.getContentType.equals("image/gif") return;
//get stream and read from it
InputStream is = conn.getInputStream();
try {
//read from is
} finally {
is.close();
}
Deuxièmement, est-il sûr pour fermer un InputStream avant tout c'est le contenu a été entièrement lu?
Il y a un risque de laisser le socket sous-jacente dans même état CLOSE_WAIT?
Vous devez vous connecter pour publier un commentaire.
Vous avez besoin de lire toutes les données dans le flux d'entrée avant de le fermer, de sorte que la connexion TCP sous-jacente mise en cache. J'ai lu qu'il ne devrait pas être nécessaire dans la dernière version de Java, mais il a toujours été mandaté pour lire l'intégralité de réponse pour le raccordement de la réutilisation.
Vérifier ce post: keep-alive dans java6
HttpUrlConnection.disconnect()
le sous-jacent tcp socket est fermée. En fermant le flux d'entrée, le sous-jacent socket tcp est commun pour les réutiliser ultérieurement.Le seul inconvénient est que l'ensemble de la réponse (OU l'ensemble de la réponse d'erreur) doit être lu dans le flux d'entrée pour la connexion tcp à être mis en cache. Cela a toujours été conseillé que vous réellement besoin de l'ensemble des données du flux. Vérifiez le post dans ma réponseSelon http://docs.oracle.com/javase/6/docs/technotes/guides/net/http-keepalive.html
et OpenJDK code source.
(Quand
keepAlive == true
)Si le client appelle
HttpURLConnection.getInputSteam().close()
, l'appeler plus tard àHttpURLConnection.disconnect()
sera PAS fermer laSocket
. c'est à dire LaSocket
est réutilisé (en cache)Si le client n'appelle pas
close()
, appeldisconnect()
va fermer leInputStream
et fermer laSocket
.Afin de réutiliser le
Socket
, il suffit d'appelerInputStream.close()
. Ne pas appelerHttpURLConnection.disconnect()
.Voici quelques informations concernant le keep-alive cache. L'ensemble de ces informations concerne la version 6 de Java, mais il est probablement aussi précis pour beaucoup avant et versions ultérieures.
De ce que je peux dire, le code se résume à:
Cette logique est partagé entre deux lieux: autour de la ligne 725 de soleil.net.www.http.HttpClient (dans le "parseHTTPHeader" la méthode), et autour de la ligne 120 de soleil.net.www.http.KeepAliveCache (dans le "mettre" de la méthode).
Donc, il y a deux façons de régler le délai d'attente
On pourrait penser qu'il serait possible de changer la apparemment arbitraire de cinq secondes par défaut sans avoir à recompiler interne les classes du JDK, mais il ne l'est pas. Un bug a été déposée en 2005, demandant cette capacité, mais le Soleil a refusé de les fournir.
Si vous voulez vraiment vous assurer que la connexion est proche, vous devez appeler
conn.disconnect()
.Les connexions ouvertes que vous avez observé à cause de la HTTP 1.1 connexion à garder vivante la fonctionnalité (aussi connu comme HTTP Connexions Persistantes).
Si le serveur supporte le protocole HTTP 1.1 et n'envoie pas un
Connection: close
dans l'en-tête de réponse, Java ne pas fermer immédiatement la sous-jacente de la connexion TCP lorsque vous fermez le flux d'entrée. Au lieu de cela il le garde ouvert et tente de les réutiliser pour la prochaine requête HTTP vers le même serveur.Si vous ne voulez pas ce comportement, vous pouvez configurer le système de la propriété
http.keepAlive
false:Vous devez également fermer le flux d'erreur si la requête HTTP a échoué (mais rien de 200):
Si vous ne le faites pas, toutes les requêtes qui ne renvoient 200 (par exemple, délai d'attente) est une fuite de la douille.
public InputStream getErrorStream() { return null; }
finally
bloc. vous pouvez utiliser le enfin fermer le flux de données au lieu decatch
Oui, il doit toujours être fermé.
Pas à 100%, vous courez le risque de contracter un NPE. La sécurité est:
IOUtils.closeQuietly(is)