145 votes

Pouvez-vous expliquer le processus de connexion HttpURLConnection?

Je suis l'aide d' HTTPURLConnection pour vous connecter à un service web. Je sais comment utiliser HTTPURLConnection , mais je veux comprendre comment il fonctionne. En gros, je veux savoir ce qui suit:

  • Sur le point n' HTTPURLConnection essayez d'établir une connexion à l'URL donnée?
  • Sur quel point puis-je savoir que j'ai été en mesure d'établir avec succès un lien?
  • Sont l'établissement d'une connexion et l'envoi de la demande réelle en une seule étape/appel de la méthode? Quelle méthode est-elle?
  • Pouvez-vous expliquer la fonction de l' getOutputStream et getInputStream en profane du terme? J'ai remarqué que lorsque le serveur je suis en train d'essayer de vous connecter est en panne, je reçois un Exception à getOutputStream. Veut-il dire qu' HTTPURLConnection va seulement commencer à établir une connexion lorsque j'invoque getOutputStream? Que diriez - getInputStream? Depuis que je suis seulement en mesure d'obtenir la réponse à l' getInputStream, alors ça veut dire que je n'ai pas envoyer une demande à l' getOutputStream encore, mais simplement d'établir une connexion? N' HttpURLConnection aller sur le serveur à la demande de réponse quand j'invoque getInputStream?
  • Ai-je raison de dire que l' openConnection crée simplement une nouvelle connexion de l'objet, mais n'établit pas encore de connexion?
  • Comment puis-je mesurer la lecture de la surcharge et de se connecter dessus?

203voto

jmort253 Points 16929
String message = URLEncoder.encode("my message", "UTF-8");

try {
    // instantiate the URL object with the target URL of the resource to
    // request
    URL url = new URL("http://www.example.com/comment");

    // instantiate the HttpURLConnection with the URL object - A new
    // connection is opened every time by calling the openConnection
    // method of the protocol handler for this URL.
    // 1. This is the point where the connection is opened.
    HttpURLConnection connection = (HttpURLConnection) url
            .openConnection();
    // set connection output to true
    connection.setDoOutput(true);
    // instead of a GET, we're going to send using method="POST"
    connection.setRequestMethod("POST");

    // instantiate OutputStreamWriter using the output stream, returned
    // from getOutputStream, that writes to this connection.
    // 2. This is the point where you'll know if the connection was
    // successfully established. If an I/O error occurs while creating
    // the output stream, you'll see an IOException.
    OutputStreamWriter writer = new OutputStreamWriter(
            connection.getOutputStream());

    // write data to the connection. This is data that you are sending
    // to the server
    // 3. No. Sending the data is conducted here. We established the
    // connection with getOutputStream
    writer.write("message=" + message);

    // Closes this output stream and releases any system resources
    // associated with this stream. At this point, we've sent all the
    // data. Only the outputStream is closed at this point, not the
    // actual connection
    writer.close();
    // if there is a response code AND that response code is 200 OK, do
    // stuff in the first if block
    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
        // OK

        // otherwise, if any other status code is returned, or no status
        // code is returned, do stuff in the else block
    } else {
        // Server returned HTTP error code.
    }
} catch (MalformedURLException e) {
    // ...
} catch (IOException e) {
    // ...
}

Les 3 premières réponses à vos questions sont répertoriés comme des commentaires en ligne, à côté de chaque méthode, dans l'exemple HTTP POST ci-dessus.

De getOutputStream:

Renvoie un flux de sortie qui écrit à cet égard.

Fondamentalement, je pense que vous avez une bonne compréhension de la façon dont cela fonctionne, permettez-moi de réitérer en termes simples. getOutputStream ouvre essentiellement une connexion flux, avec l'intention d'écriture de données sur le serveur. Dans le code ci-dessus l'exemple "message" pourrait être un commentaire que nous allons envoyer au serveur qui représente un commentaire laissé sur un post. Quand vous voyez getOutputStream, vous êtes à l'ouverture de la connexion flux pour l'écriture, mais vous ne vous sentez pas à l'écriture de toutes les données jusqu'à ce que vous appelez writer.write("message=" + message);.

De getInputStream():

Retourne un flux d'entrée qui lit à partir de cette connexion. Un SocketTimeoutException peut être levée lors de la lecture de l'retourné flux d'entrée si le délai d'attente expire avant que les données sont disponibles pour la lecture.

getInputStream fait le contraire. Comme getOutputStream, il ouvre également une connexion flux, mais l'intention est de lire les données à partir du serveur, pas écrire. Si la connexion ou de flux d'ouverture échoue, vous verrez SocketTimeoutException.

Comment au sujet de la getInputStream? Depuis que je suis seulement en mesure d'obtenir la réponse à getInputStream, alors ça veut dire que je n'ai pas envoyer de demande à getOutputStream encore, mais simplement d'établir une connexion?

Gardez à l'esprit que l'envoi d'une demande et l'envoi de données sont deux opérations différentes. Lorsque vous appelez getOutputStream ou getInputStream url.openConnection(), de vous envoyer une demande au serveur pour établir une connexion. Il y a une poignée de main qui se produit lorsque le serveur renvoie un accusé de réception vous que la connexion est établie. C'est alors à ce point dans le temps que vous êtes prêt à envoyer ou recevoir des données. Ainsi, vous n'avez pas besoin d'appeler getOutputStream pour établir une connexion ouvrir un flux, à moins que votre objectif pour faire la demande est à envoyer des données.

En d'autres termes, faire une getInputStream demande est l'équivalent de faire un appel téléphonique à un ami pour lui dire "Hé, est-ce correct si je viens et emprunter la paire de vice-poignées?" et votre ami établit la poignée de main en disant: "bien Sûr! Come and get it". Alors, à ce moment, la connexion est établie, vous marchez à votre ami, frapper à la porte, à la demande de la vice grips, et retournez à votre maison.

À l'aide d'un exemple similaire pour getOutputStream impliquerait d'appeler votre ami en disant "Hey, j'ai de l'argent que je vous dois, puis-je l'envoyer à vous"? Votre ami, ayant besoin d'argent et des malades à l'intérieur que vous avez gardé si longtemps, dit "bien Sûr, venez par vous à bas prix bâtard". Si vous marchez à votre ami et "POST" de l'argent pour lui. Ensuite, il vous coups de pied et vous retournez à votre maison.

Maintenant, en continuant avec le profane exemple, jetons un oeil à quelques Exceptions près. Si vous avez appelé votre ami et qu'il n'était pas à la maison, qui pourrait être une erreur 500. Si vous avez appelé et a obtenu à la déconnexion d'un numéro de message parce que votre ami est fatigué de vous emprunter de l'argent tout le temps, c'est une erreur 404 page non trouvée. Si votre téléphone est mort parce que vous n'avez pas payé le projet de loi, qui pourrait être une IOException. (REMARQUE: Cette section ne peut pas être 100% correct. Il est destiné à vous donner une idée générale de ce qui se passe dans d'autres termes.)

Question #5:

Oui, il est exact que les openConnection crée simplement une nouvelle connexion de l'objet, mais ne permet pas de l'établir. La connexion est établie lorsque l'appel soit getInputStream ou getOutputStream.

openConnection crée un nouvel objet de connexion. À partir de l' URL.openConnection javadoc:

Une nouvelle connexion est ouverte à tout moment en appelant la méthode openConnection du gestionnaire de protocole pour cette URL.

La connexion est établie lorsque vous appelez openConnection, et l'InputStream, OutputStream, ou les deux, sont appelées lorsque vous les instancier.

Question #6:

Pour mesurer la surcharge, en général, je enveloppez très simple code de timing autour de l'ensemble du bloc de connexion, comme suit:

long start = System.currentTimeMillis();
log.info("Time so far = " + new Long(System.currentTimeMillis() - start) );

// run the above example code here
log.info("Total time to send/receive data = " + new Long(System.currentTimeMillis() - start) );

Je suis sûr qu'il y a des méthodes plus avancées pour mesurer le temps de la demande et les frais généraux, mais en général, cela est suffisant pour mes besoins.

Pour plus d'informations sur la fermeture des connexions, que vous ne demandez pas à ce sujet, voir En Java quand une URL de connexion à proximité?.

18voto

anonymous Points 61

Tim Bray a présenté de manière concise, étape par étape, indiquant qu'openConnection () n'établit pas de connexion réelle. Au lieu de cela, une connexion HTTP réelle n'est pas établie jusqu'à ce que vous appeliez des méthodes telles que getInputStream () ou getOutputStream ().

http://www.tbray.org/ongoing/When/201x/2012/01/17/HttpURLConnection

3voto

EJP Points 113412

Sur le point de ne HTTPURLConnection essayez d'établir une connexion à l'URL donnée?

Sur le port nommé dans l'URL, le cas échéant, sinon de 80 pour HTTP et 443 pour HTTPS. Je crois que c'est documenté.

Sur quel point puis-je savoir que j'ai été en mesure d'établir avec succès un lien?

Lorsque vous appelez getInputStream() ou getOutputStream() ou getResponseCode() sans se faire une exception.

Sont l'établissement d'une connexion et l'envoi de la demande réelle en une seule étape/appel de la méthode? Quelle méthode est-elle?

Aucun et aucune.

Pouvez-vous expliquer la fonction de getOutputStream et getInputStream en profane du terme?

L'un d'eux se connecte tout d'abord, si nécessaire, puis remet les flux.

J'ai remarqué que lorsque le serveur je suis en train d'essayer de vous connecter est en panne, je reçois une Exception à getOutputStream. Ça veut dire que HTTPURLConnection va seulement commencer à établir une connexion lorsque j'invoque getOutputStream? Comment au sujet de la getInputStream? Depuis que je suis seulement en mesure d'obtenir la réponse à getInputStream, alors ça veut dire que je n'ai pas envoyer de demande à getOutputStream encore, mais simplement d'établir une connexion? Ne HttpURLConnection aller vers le serveur de demande de réponse quand j'invoque getInputStream?

Voir ci-dessus.

Ai-je raison de dire que openConnection crée simplement une nouvelle connexion de l'objet, mais n'établit pas encore de connexion?

Oui.

Comment puis-je mesurer la lecture de la surcharge et de se connecter dessus?

Connect: prenez le temps getInoutStream() ou getOutputStream() prend de revenir, selon ce que vous appeler en premier. Lire: l'heure de départ de la première lecture à l'obtention de l'EOS.

1voto

Tim Cooper Points 2481

Sur le point de ne HTTPURLConnection essayez d'établir une connexion à l'URL donnée?

Il vaut la peine de clarifier, il y a le 'UrlConnection' instance et puis il y a le sous-jacent Tcp/Ip/SSL connexion de socket, 2 concepts différents. Le "UrlConnection" ou "HttpUrlConnection' instance est synonyme d'une seule page HTTP de la requête, et est créé lors de l'appel de l'url.openConnection(). Mais si vous le faites plusieurs url.openConnection()'partir de l'un 'url' instance alors si vous avez de la chance, ils vont réutiliser le même socket Tcp/Ip et le protocole SSL handshake choses...ce qui est bon si vous faites beaucoup de demandes de page sur le même serveur, particulièrement bon si vous utilisez SSL, où les frais généraux de l'établissement de la socket est très élevé.

Voir: HttpURLConnection mise en œuvre

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X