HttpClient Java obsoleto: quanto può essere difficile?


172

Tutto quello che sto cercando di fare è scaricare alcuni JSON e deserializzarli in un oggetto. Non ho ancora ottenuto il download di JSON.

Quasi ogni singolo esempio di HttpClient che riesco a trovare, compresi quelli sul sito di Apache, assomiglia a ...

import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;

public void blah() {
    HttpClient client = new DefaultHttpClient();
    ...
}

Tuttavia, Netbeans mi dice che DefaultHttpClientè deprecato. Ho provato a cercare su Google DefaultHttpClient deprecatede quante altre varianti mi viene in mente e non riesco a trovare alcun risultato utile, quindi ovviamente mi manca qualcosa.

Qual è il modo Java7 corretto per scaricare i contenuti di una pagina Web? Non esiste davvero un client HTTP decente come parte della lingua? Lo trovo difficile da credere.

La mia dipendenza Maven per questo è ...

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>LATEST</version>
    <type>jar</type>
</dependency>

2
NetBeans ti sta dicendo male o stai leggendo male qualcosa. DefaultHttpClientnon è sicuramente deprecato. Quale versione hai specificato nel tuo POM?
Percezione

8
in 4.3-alpha1 sembra essere deprecato
Arun P Johny

3
Hai ragione l'API httpclient è un disastro ferroviario
Hans Westerbeek,

2
Ti consiglio di impostare la versione su un numero di versione maggiore invece di ULTIMO. Ciò ti consentirà di controllare manualmente il processo di aggiornamento e di non lasciare che Maven decida per te.
Christophe Roussy,

1
@Basic può cambiare in qualsiasi momento mentre ci lavori anche in un nuovo progetto, questo potrebbe creare confusione se non l'hai impostato tu stesso. Ad esempio ha funzionato e compilato e tu commetti il ​​codice. Qualcun altro arriva il giorno successivo, checkout e non si compila nemmeno perché la versione ULTIMA è cambiata. Ovviamente fai quello che vuoi ma eviterei di usarlo per questo motivo (versionning).
Christophe Roussy,

Risposte:


259

Importazioni rilevanti:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.IOException;

Uso:

HttpClient httpClient = HttpClientBuilder.create().build();

EDIT (dopo il suggerimento di Jules):

Poiché il build()metodo restituisce a CloseableHttpClientche è -a AutoClosable , è possibile inserire la dichiarazione in un'istruzione try-with-resources (Java 7+):

try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {

    // use httpClient (no need to close it explicitly)

} catch (IOException e) {

    // handle

}

2
Stai utilizzando la versione precedente alla 4.3 (e dovrebbe essere Apache HTTPClient, non Commons HTTPClient)
Alfishe

7
Si noti che il valore restituito è a CloseableHttpClient, che si dovrebbe chiudere dopo l'uso. Essa attua AutoCloseable, in modo da poter utilizzare in un'istruzione try-with-risorse in Java 7+: try (CloseableHttpClient httpclient = ...) { ... }.
Jules,

2
CloseableHttpClient httpClient = HttpClientBuilder.create (). Build (); questo lavoro per me
Sameer Kazi,

6
Domanda: dovremmo aggrapparci all'istanza di HttpClientBuilder restituita dal create()metodo statico? O possiamo semplicemente chiamare create()ogni volta che ne abbiamo bisogno? ... A proposito, import org.apache.http.impl.client.HttpClientBuilderper chiunque ne abbia bisogno. [Non ama le risposte senza dichiarazioni di importazione. Non ti preoccupare, ho ancora votato :)]
ADTC

1
@HartmutPfitzinger usa OkHttp su Android. Hanno incasinato un Apache Http Client biforcuto, che ora è ereditato.
sschrass,

59

IMHO la risposta accettata è corretta ma manca un po 'di' insegnamento 'in quanto non spiega come trovare la risposta. Per tutte le classi deprecate guarda JavaDoc (se non lo hai, scaricalo o vai online ), suggerirà quale classe usare per sostituire il vecchio codice. Ovviamente non ti dirà tutto, ma questo è un inizio. Esempio:

...
 *
 * @deprecated (4.3) use {@link HttpClientBuilder}.  <----- THE HINT IS HERE !
 */
@ThreadSafe
@Deprecated
public class DefaultHttpClient extends AbstractHttpClient {

Ora si ha la classe da utilizzare, HttpClientBuilder, in quanto non v'è alcun costruttore per ottenere un costruttore di esempio si può immaginare che ci deve essere un metodo statico invece: create. Una volta che hai il builder puoi anche immaginare che, come per la maggior parte dei costruttori, esiste un metodo di compilazione , quindi:

org.apache.http.impl.client.HttpClientBuilder.create().build();

AutoClosable:

Come ha suggerito Jules nei commenti, la classe restituita implementa java.io.Closable, quindi se usi Java 7 o versioni successive ora puoi fare:

    try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {...}

Il vantaggio è che non devi affrontare finalmente e null.

Altre informazioni rilevanti

Assicurati anche di leggere il pool di connessioni e impostare i timeout .


11

Esempi di Apache usano questo:

CloseableHttpClient httpclient = HttpClients.createDefault();

La classe org.apache.http.impl.client.HttpClientsè presente dalla versione 4.3.

Il codice per HttpClients.createDefault()è lo stesso della risposta accettata qui.


ottieni errore "Causato da: java.lang.VerifyError: org / apache / http / conn / ssl / DefaultHostnameVerifier" quando usi HttpClient client = HttpClients.createDefault ();
Md Imran Choudhury,

7

È diventato obsoleto nella versione 4.3-alpha1utilizzata a causa delle LATESTspecifiche della versione. Se si dà un'occhiata al Javadoc della classe, ti dice cosa usare invece: HttpClientBuilder.

Nell'ultima versione stabile ( 4.2.3) DefaultHttpClientnon è ancora obsoleto.


Grazie per la risposta - Netbeans non mostra alcun JavaDocs per nessuna delle cose di org.apache - ma suppongo che sia un problema diverso
Basic

Probabilmente non hai i sorgenti collegati alla libreria. Non uso Netbeans, ma suppongo che ci sia un modo per chiedergli di scaricare le fonti delle dipendenze.
zagyi


4

Suggerirei di utilizzare il metodo seguente se stai cercando di leggere solo i dati json.

URL requestUrl=new URL(url);
URLConnection con = requestUrl.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder sb=new StringBuilder();
int cp;
try {
    while((cp=rd.read())!=-1){
    sb.append((char)cp);
  }
 catch(Exception e){
 }
 String json=sb.toString();

Le domande dicono che DefaultHttpClientè deprecato e tu suggerisci di usarlo nella tua risposta ...
Basic

Grazie per l'approccio alternativo. Sono già andato con la risposta accettata, ma questo sembra abbastanza leggero che ci proverò la prossima volta.
Base

2

Utilizzare HttpClientBuilder per creare HttpClient invece di utilizzare DefaultHttpClient

ex:

MinimalHttpClient httpclient = new HttpClientBuilder().build();

 // Prepare a request object
 HttpGet httpget = new HttpGet("http://www.apache.org/");

Perché new HttpClientBuilder()e no HttpClientBuilder.create()?
ADTC,

2

È possibile aggiungere la seguente dipendenza Maven.

    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime -->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpmime</artifactId>
        <version>4.5.1</version>
    </dependency>

È possibile utilizzare la seguente importazione nel codice java.

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGett;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.client.methods.HttpUriRequest;

È possibile utilizzare il seguente blocco di codice nel codice java.

HttpClient client = HttpClientBuilder.create().build();
HttpUriRequest httpUriRequest = new HttpGet("http://example.domain/someuri");

HttpResponse response = client.execute(httpUriRequest);
System.out.println("Response:"+response);

Grazie per aver dedicato del tempo a rispondere, ma in cosa differisce dalla risposta accettata?
Basic

1
La maggior parte delle risposte sono codici psuedo, ho provato a creare un codice Java funzionante di base end-to-end con l'API client HTTP Apache insieme alla dipendenza maven. Niente di eccezionale però.
Red Boy

1

Questa è la soluzione che ho applicato al problema che httpclient ha deprecato in questa versione di Android 22

 public static String getContenxtWeb(String urlS) {
    String pagina = "", devuelve = "";
    URL url;
    try {
        url = new URL(urlS);
        HttpURLConnection conexion = (HttpURLConnection) url
                .openConnection();
        conexion.setRequestProperty("User-Agent",
                "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
        if (conexion.getResponseCode() == HttpURLConnection.HTTP_OK) {
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(conexion.getInputStream()));
            String linea = reader.readLine();
            while (linea != null) {
                pagina += linea;
                linea = reader.readLine();
            }
            reader.close();

            devuelve = pagina;
        } else {
            conexion.disconnect();
            return null;
        }
        conexion.disconnect();
        return devuelve;
    } catch (Exception ex) {
        return devuelve;
    }
}

-2

Per il problema originale, ti chiederei di applicare la logica seguente:

 CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 HttpPost httpPostRequest = new HttpPost();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.