Deprecated Java HttpClient - How hard can it be?
Asked Answered
E

9

181

All I'm trying to do is download some JSON and deserialize it into an object. I haven't got as far as downloading the JSON yet.

Almost every single HttpClient example I can find, including those on the apache site looks something like...

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

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

However, Netbeans tells me that DefaultHttpClient is deprecated. I've tried googling for DefaultHttpClient deprecated and as many other variations as I can think of and can't find any useful results, so I'm obviously missing something.

What is the correct Java7 way to download the contents of a webpage? Is there really no decent Http Client as part of the language? I find that hard to believe.

My Maven dependency for this is...

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>LATEST</version>
    <type>jar</type>
</dependency>
Emmaline answered 11/3, 2013 at 10:38 Comment(10)
NetBeans is telling you wrong, or you are misreading something. DefaultHttpClient is definitely not deprecated. What version did you specify in your POM?Consciousness
in 4.3-alpha1 it seems to be deprecatedQuezada
@sreemanth Thanks but although I eventually intend to use this for Json, the actual question is not related to Json at all.Emmaline
You are right the httpclient API is a trainwreckBayne
I would recommend you set the version to some major release number instead of LATEST. This will allow you to manually control the upgrade process and not let Maven decide for you.Bravura
@ChristopheRoussy Sure, when you've finished writing it... But for your first piece of code in a new project, why not use Latest? Once you've actually got a dependency on a specific version, absolutely nail it downEmmaline
@Emmaline it may change any time while you work on it even in a new project, this may be confusing if you did not set it yourself. For example it worked and compiled and you commit the code. Someone else arrives the next day, checkout and it does not even compile because the LATEST version changed. Of course you do what you want but I would avoid using it for this reason (versionning).Bravura
@ChristopheRoussy Let's agree to disagreeEmmaline
I think it's worth noting here that with Java 11 now comes a built in HttpClient and possibly freedom from the apache dependency for some applications, depending on your needs.Freshman
@CaseyMurray That's very welcome indeed, if long overdue.Emmaline
B
275

Relevant imports:

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

Usage:

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

EDIT (after Jules' suggestion):

As the build() method returns a CloseableHttpClient which is-a AutoClosable, you can place the declaration in a try-with-resources statement (Java 7+):

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

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

} catch (IOException e) {

    // handle

}
Bibliolatry answered 11/3, 2013 at 10:55 Comment(10)
This is giving me - Exception in thread "main" java.lang.NoSuchFieldError: INSTANCEGraniah
You're using version below 4.3 (and it should be Apache HTTPClient, not Commons HTTPClient)Recessional
Note that the return value is a CloseableHttpClient, which you should be closing after use. It implements AutoCloseable, so you can use it in a try-with-resources statement in Java 7+: try (CloseableHttpClient httpclient = ...) { ... }.Procedure
how to build within a Spring xml config. file?Rema
CloseableHttpClient httpClient = HttpClientBuilder.create().build(); this work for mePyrogallol
Question: Should we hold on to the HttpClientBuilder instance returned by the create() static method? Or can we just call create() whenever we need one?... Btw, import org.apache.http.impl.client.HttpClientBuilder for anyone who needs that. [Dislikes answers without import statements. Don't worry I still upvoted :)]Shalloon
can also use CloseableHttpClient httpClient = HttpClients.createDefault()Factotum
With API 23 this becomes much more complicated: hc.apache.org/httpcomponents-client-4.5.x/android-port.htmlHustler
@HartmutPfitzinger use OkHttp on Android. They messed up with a forked Apache Http Client, that is now legacy.Tupler
i am getting this error "Caused by: java.lang.NoSuchFieldError: No static field INSTANCE of type Lorg/apache/http/conn/ssl/AllowAllHostnameVerifier; in class Lorg/apache/http/conn/ssl/AllowAllHostnameVerifier; or its superclasses (declaration of 'org.apache.http.conn.ssl.AllowAllHostnameVerifier' appears in /system/framework/framework.jar!classes3.dex) at org.apache.http.conn.ssl.SSLConnectionSocketFactory.<clinit>(SSLConnectionSocketFactory.java:151) at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:977)"Cuneal
B
60

IMHO the accepted answer is correct but misses some 'teaching' as it does not explain how to come up with the answer. For all deprecated classes look at the JavaDoc (if you do not have it either download it or go online), it will hint at which class to use to replace the old code. Of course it will not tell you everything, but this is a start. Example:

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

Now you have the class to use, HttpClientBuilder, as there is no constructor to get a builder instance you may guess that there must be a static method instead: create. Once you have the builder you can also guess that as for most builders there is a build method, thus:

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

AutoClosable:

As Jules hinted in the comments, the returned class implements java.io.Closable, so if you use Java 7 or above you can now do:

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

The advantage is that you do not have to deal with finally and nulls.

Other relevant info

Also make sure to read about connection pooling and set the timeouts.

Bravura answered 19/11, 2014 at 13:18 Comment(0)
B
13

Examples from Apache use this:

CloseableHttpClient httpclient = HttpClients.createDefault();

The class org.apache.http.impl.client.HttpClients is there since version 4.3.

The code for HttpClients.createDefault() is the same as the accepted answer in here.

Bryannabryansk answered 2/9, 2015 at 23:33 Comment(1)
get error "Caused by: java.lang.VerifyError: org/apache/http/conn/ssl/DefaultHostnameVerifier" when use HttpClient client = HttpClients.createDefault();Arrest
A
7

It got deprecated in version 4.3-alpha1 which you use because of the LATEST version specification. If you take a look at the javadoc of the class, it tells you what to use instead: HttpClientBuilder.

In the latest stable version (4.2.3) the DefaultHttpClient is not deprecated yet.

Algae answered 11/3, 2013 at 10:45 Comment(2)
Thanks for the response - Netbeans isn't showing any JavaDocs for any of the org.apache stuff - but I suppose that's a different problemEmmaline
You probably don't have the sources attached to the library. I don't use Netbeans, but I guess there is a way to ask it to download the sources of the dependencies.Algae
R
4

I would suggest using the below method if you are trying to read the json data only.

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();
Rida answered 11/3, 2013 at 10:55 Comment(2)
The questions says DefaultHttpClient is deprecated and you suggest using it in your answer...Emmaline
Thanks for the alternate approach. I've already gone with the acdepted answer but this looks light-weight enough that I'll give it a try next time.Emmaline
Q
2

Use HttpClientBuilder to build the HttpClient instead of using DefaultHttpClient

ex:

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

 // Prepare a request object
 HttpGet httpget = new HttpGet("http://www.apache.org/");
Quezada answered 11/3, 2013 at 10:48 Comment(1)
Why new HttpClientBuilder() and not HttpClientBuilder.create()?Shalloon
R
2

You could add the following Maven dependency.

    <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>

You could use following import in your java code.

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;

You could use following code block in your java code.

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

HttpResponse response = client.execute(httpUriRequest);
System.out.println("Response:"+response);
Ritualism answered 2/4, 2018 at 6:19 Comment(2)
Thanks for taking the time to answer, but how is this different from the accepted answer?Emmaline
Most of answers are psuedo codes, I tried doing an end-to-end basic working Java code with Apache HTTP Client API along with maven dependency. Nothing great though.Ritualism
A
1

This is the solution that I have applied to the problem that httpclient deprecated in this version of 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;
    }
}
Arsenical answered 1/9, 2015 at 8:3 Comment(0)
F
-2

For the original issue, I would request you to apply below logic:

 CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 HttpPost httpPostRequest = new HttpPost();
First answered 22/4, 2014 at 12:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.