Постоянное HttpURLConnection в Java

Я пытаюсь написать Java-программу, которая автоматически загрузит и назовет некоторые из моих любимых веб-комиксов. Поскольку я буду запрашивать несколько объектов из одного и того же домена, я хотел иметь постоянное http-соединение, которое я мог бы держать открытым, пока все комиксы не будут загружены. Ниже моя незавершенная работа. Как сделать еще один запрос из того же домена, но по другому пути, не открывая новое http-соединение?

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class ComicDownloader
{
    public static void main(String[] args)
    {
        URL url = null;
        HttpURLConnection httpc = null;
        BufferedReader input = null;

        try
        {
            url = new URL("http://www.cad-comic.com/cad/archive/2002");
            httpc = (HttpURLConnection) url.openConnection();
            input = new BufferedReader(new InputStreamReader(httpc.getInputStream()));
            String inputLine;

            while ((inputLine = input.readLine()) != null)
            {
                System.out.println(inputLine);
            }

            input.close();
            httpc.disconnect();
        }
        catch (IOException ex)
        {
            System.out.println(ex);
        }
    }
}

person Githaron    schedule 21.07.2010    source источник


Ответы (3)


Согласно здесь, HTTP Сохранение прозрачно обрабатывается в Java, хотя оно также дает вам возможность управлять им через системные свойства http.keepAlive и http.maxConnections.

Тем не мение,

Текущая реализация не буферизует тело ответа. Это означает, что приложение должно закончить чтение тела ответа или вызвать close(), чтобы отказаться от остальной части тела ответа, чтобы это соединение можно было использовать повторно. Кроме того, текущая реализация не будет пытаться читать блоки при очистке соединения, то есть, если все тело ответа недоступно, соединение не будет использоваться повторно.

Взгляните на ссылку и посмотрите, действительно ли она вам поможет.

person yclian    schedule 21.07.2010
comment
ссылка умерла? также применимо ли это к более новым версиям java? - person rogerdpack; 09.10.2013
comment
@royerdpack Конечно, да. Вы не можете серьезно поверить, что они уберут такую ​​ценную функцию. - person user207421; 10.01.2014
comment
@rogerdpack В следующий раз используйте поиск Google следующим образом: https://www.google.com/search?q=java+api+doc+net%2Fhttp-keepalive.html Тем временем исправляю ссылку. - person yclian; 11.01.2014
comment
Завершите чтение и не вызывайте close() для входного или выходного потока. Вызов close() заставил мой клиентский код повторно открыть HTTPS-соединение. - person Vladimir Dyuzhev; 23.05.2016
comment
FWIW Я думаю, что однажды прочитал stackoverflow.com/a/4767595/32453, что вызов разъединения (как это делает OP) также вызывает Сокет нельзя повторно использовать/кэшировать... - person rogerdpack; 30.12.2017

По этой ссылке http://docs.oracle.com/javase/6/docs/technotes/guides/net/http-keepalive.html, повторное использование HTTP-соединения включено по умолчанию, вы можете использовать Wireshark для проверки взаимодействия между вашим клиентом и сервером. Первый запрос содержит рукопожатия TCP и SSL (если ваш запрос https), последующие запросы, запускаемые в течение времени поддержания активности, не содержат рукопожатий TCP и SSL, только передачу данных приложения.

person allen zhang    schedule 16.02.2017

Хотя HttpURLConnection по умолчанию включает поддержку активности, не гарантируется, что HttpURLConnection использует одно и то же TCP-соединение для нескольких HTTP-запросов. Я столкнулся с такой же проблемой при написании клиентского приложения HTTPS. Эта проблема решена с помощью одного экземпляра SSLContext, SSLSocketFactory и HttpsURLConnection.

public class MyHTTPClient {
    private SSLContext mSSLContext = null;
    private SSLSocketFactory mSSLSocketFactory = null;
    private HttpsURLConnection mConnection = null;

    public void init() {
        //Setup SSL context and Socket factory here
    }

    pubblic void sendRequest() {
        URL url = new URL("https://example.com/request_receiver");
        mConnection = (HttpsURLConnection) url.openConnection();
        mConnection.setSSLSocketFactory(mSSLSocketFactory);

        // Setup request property and send request
        // Open input stream to read response
        // Close output, input streams
        
        mConnection.disconnect();
    }
}
person Harish    schedule 12.03.2021