HttpClient Java obsoleto - Quão difícil pode ser?

172

Tudo o que estou tentando fazer é baixar JSON e desserializar para um objeto. Ainda não consegui baixar o JSON.

Quase todos os exemplos de HttpClient que posso encontrar, incluindo os do site apache, são parecidos com ...

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

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

No entanto, o Netbeans me diz que DefaultHttpClientestá obsoleto. Eu tentei pesquisar no Google DefaultHttpClient deprecatede em tantas outras variações em que consigo pensar e não consigo encontrar resultados úteis, então obviamente estou perdendo alguma coisa.

Qual é a maneira correta do Java7 de baixar o conteúdo de uma página da web? Não existe realmente nenhum cliente Http decente como parte do idioma? Acho isso difícil de acreditar.

Minha dependência do Maven para isso é ...

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>LATEST</version>
    <type>jar</type>
</dependency>
Basic
fonte
2
O NetBeans está dizendo errado ou você está lendo algo errado. DefaultHttpClientdefinitivamente não está obsoleto. Qual versão você especificou no seu POM?
Perception
8
em 4,3-alfa1 parece ser preterido
Arun P Johny
3
Você está certo, a API httpclient é um naufrágio
Hans Westerbeek
2
Eu recomendo que você defina a versão com algum número de versão principal em vez de LATEST. Isso permitirá que você controle manualmente o processo de atualização e não permita que o Maven decida por você.
Christophe Roussy
1
@Basic pode mudar a qualquer momento enquanto você trabalha nele, mesmo em um novo projeto, isso pode ser confuso se você não o tiver definido. Por exemplo, funcionou e compilou e você confirma o código. Alguém chega no dia seguinte, faz o checkout e ele nem é compilado porque a versão MAIS RECENTE foi alterada. Claro que você faz o que deseja, mas eu evitaria usá-lo por esse motivo (versionamento).
Christophe Roussy

Respostas:

259

Importações relevantes:

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 (após sugestão de Jules):

Como o build()método retorna a CloseableHttpClientque é-a AutoClosable , você pode colocar a declaração em uma instrução try-with-resources (Java 7+):

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

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

} catch (IOException e) {

    // handle

}
hthserhs
fonte
2
Você está usando a versão abaixo de 4,3 (e deve ser Apache HTTPClient, não Commons HttpClient)
Alfishe
7
Observe que o valor de retorno é a CloseableHttpClient, que você deve fechar após o uso. Ele implementa AutoCloseable, assim você pode usá-lo em uma instrução try-with-recursos em Java 7+: try (CloseableHttpClient httpclient = ...) { ... }.
Jules
2
CloseableHttpClient httpClient = HttpClientBuilder.create (). Build (); este trabalho para mim #
Sameer Kazi
6
Pergunta: Devemos manter a instância HttpClientBuilder retornada pelo create()método estático? Ou podemos simplesmente ligar create()sempre que precisarmos de um? ... Aliás, import org.apache.http.impl.client.HttpClientBuilderpara quem precisa disso. [Não gosta de respostas sem instruções de importação. Não se preocupe, eu ainda votei :)]
ADTC
1
@HartmutPfitzinger usa OkHttp no Android. Eles estragaram tudo com um Apache Http Client bifurcado, que agora é legado.
sschrass
59

IMHO, a resposta aceita está correta, mas perde alguns 'ensinamentos', pois não explica como chegar à resposta. Para todas as classes obsoletas, observe o JavaDoc (se você não o tiver baixado ou online ), ele indicará qual classe usar para substituir o código antigo. Claro que não vai lhe contar tudo, mas isso é um começo. Exemplo:

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

Agora você tem a classe para usar, HttpClientBuildercomo não há nenhum construtor para obter um construtor exemplo, você pode acho que deve haver um método estático em vez disso: create. Depois de ter o construtor, você também pode supor que, para a maioria dos construtores, existe um método de construção , assim:

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

AutoClosable:

Como Jules sugeriu nos comentários, a classe retornada é implementada java.io.Closable; portanto, se você usa o Java 7 ou superior, agora pode:

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

A vantagem é que você não precisa lidar com finalmente e nulos.

Outras informações relevantes

Leia também sobre o pool de conexões e defina os tempos limite .

Christophe Roussy
fonte
11

Exemplos do Apache usam isso:

CloseableHttpClient httpclient = HttpClients.createDefault();

A classe org.apache.http.impl.client.HttpClientsexiste desde a versão 4.3.

O código para HttpClients.createDefault()é o mesmo que a resposta aceita aqui.

IvanRF
fonte
obtenha o erro "Causado por: java.lang.VerifyError: org / apache / http / conn / ssl / DefaultHostnameVerifier" ao usar o cliente HttpClient = cliente HttpClient = HttpClients.createDefault ();
Md Imran Choudhury
7

Foi preterido na versão 4.3-alpha1que você usa devido à LATESTespecificação da versão. Se você der uma olhada no javadoc da classe, diz-lhe o que usar em vez disso: HttpClientBuilder.

Na versão estável mais recente ( 4.2.3), DefaultHttpClientisso ainda não foi preterido.

zagyi
fonte
Obrigado pela resposta - Netbeans não está mostrando nenhum JavaDocs para nenhuma das coisas org.apache - mas eu suponho que é um problema diferente
Básico
Você provavelmente não tem as fontes anexadas à biblioteca. Eu não uso o Netbeans, mas acho que há uma maneira de solicitar o download das fontes das dependências.
zagyi
7

Tente jcabi-http, que é um cliente Java HTTP fluente, por exemplo:

String html = new JdkRequest("https://www.google.com")
  .header(HttpHeaders.ACCEPT, MediaType.TEXT_HTML)
  .fetch()
  .as(HttpResponse.class)
  .assertStatus(HttpURLConnection.HTTP_OK)
  .body();

Verifique também esta postagem do blog: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

yegor256
fonte
4

Eu sugeriria o uso do método abaixo se você estiver tentando ler apenas os dados do 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();
Anubhab
fonte
As perguntas dizem que DefaultHttpClientfoi descontinuado e você sugere usá-lo em sua resposta ... #
Basic
Obrigado pela abordagem alternativa. Eu já fui com a resposta aceita, mas isso parece leve o suficiente para que eu tente na próxima vez.
Básico
2

Use HttpClientBuilder para criar o HttpClient em vez de usar DefaultHttpClient

ex:

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

 // Prepare a request object
 HttpGet httpget = new HttpGet("http://www.apache.org/");
Arun P Johny
fonte
Por que new HttpClientBuilder()e não HttpClientBuilder.create()?
ADTC
2

Você pode adicionar a seguinte dependência do 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>

Você pode usar a seguinte importação no seu código 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;

Você pode usar o seguinte bloco de código no seu código java.

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

HttpResponse response = client.execute(httpUriRequest);
System.out.println("Response:"+response);
Menino vermelho
fonte
Obrigado por reservar um tempo para responder, mas como isso é diferente da resposta aceita?
Basic
1
A maioria das respostas são códigos psuedo. Tentei criar um código Java básico de ponta a ponta com a API do cliente HTTP Apache, juntamente com a dependência do maven. Nada ótimo embora.
Red Boy
1

Esta é a solução que apliquei ao problema que o httpclient reprovou nesta versão do 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;
    }
}
Frutos Marquez
fonte
-2

Para o problema original, solicitei que você aplique abaixo da lógica:

 CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 HttpPost httpPostRequest = new HttpPost();
Pra_A
fonte