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>
Basic
  • 26,321
  • 24
  • 115
  • 201
  • 2
    NetBeans is telling you wrong, or you are misreading something. `DefaultHttpClient` is definitely not deprecated. What version did you specify in your POM? – Perception Mar 11 '13 at 10:41
  • 8
    in 4.3-alpha1 it seems to be deprecated – Arun P Johny Mar 11 '13 at 10:45
  • @sreemanth Thanks but although I eventually intend to use this for Json, the actual question is not related to Json at all. – Basic Mar 11 '13 at 10:49
  • 3
    You are right the httpclient API is a trainwreck – Hans Westerbeek Jun 18 '14 at 08:10
  • 2
    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. – Christophe Roussy Nov 19 '14 at 14:14
  • @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 down – Basic Nov 19 '14 at 14:52
  • 1
    @Basic 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). – Christophe Roussy Nov 19 '14 at 16:02
  • 1
    @ChristopheRoussy Let's agree to disagree – Basic Nov 19 '14 at 17:06
  • 1
    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. – Casey Murray Mar 06 '19 at 15:33
  • @CaseyMurray That's very welcome indeed, if long overdue. – Basic Mar 06 '19 at 15:50

9 Answers9

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

}
NoBrainer
  • 5,853
  • 1
  • 27
  • 27
  • This is giving me - Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE – jagamot Mar 11 '14 at 16:14
  • 2
    You're using version below 4.3 (and it should be Apache HTTPClient, not Commons HTTPClient) – Alfishe Mar 15 '14 at 15:58
  • 7
    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 = ...) { ... }`. – Jules Apr 19 '14 at 05:35
  • how to build within a Spring xml config. file? – Luís Soares Aug 05 '14 at 10:53
  • 2
    CloseableHttpClient httpClient = HttpClientBuilder.create().build(); this work for me – Sameer Kazi Oct 31 '14 at 06:09
  • 7
    **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 :)]* – ADTC Jul 14 '15 at 07:10
  • can also use `CloseableHttpClient httpClient = HttpClients.createDefault()` – Paul Dec 14 '15 at 09:34
  • With API 23 this becomes much more complicated: https://hc.apache.org/httpcomponents-client-4.5.x/android-port.html – Hartmut Pfitzinger Jun 14 '16 at 05:41
  • 1
    @HartmutPfitzinger use OkHttp on Android. They messed up with a forked Apache Http Client, that is now legacy. – sschrass Nov 25 '16 at 10:03
  • 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.(SSLConnectionSocketFactory.java:151) at org.apache.http.impl.client.HttpClientBuilder.build(HttpClientBuilder.java:977)" – charitha amarasinghe Mar 24 '21 at 18:43
61

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.

Christophe Roussy
  • 16,299
  • 4
  • 85
  • 85
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.

IvanRF
  • 7,115
  • 5
  • 47
  • 71
  • get error "Caused by: java.lang.VerifyError: org/apache/http/conn/ssl/DefaultHostnameVerifier" when use HttpClient client = HttpClients.createDefault(); – Md Imran Choudhury Jul 06 '17 at 05:47
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.

zagyi
  • 17,223
  • 4
  • 51
  • 48
  • Thanks for the response - Netbeans isn't showing any JavaDocs for any of the org.apache stuff - but I suppose that's a different problem – Basic Mar 11 '13 at 10:47
  • 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. – zagyi Mar 11 '13 at 10:49
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();
Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
Anubhab
  • 1,736
  • 2
  • 18
  • 28
  • The questions says `DefaultHttpClient` is deprecated and you suggest using it in your answer... – Basic Mar 11 '13 at 10:57
  • 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. – Basic Mar 11 '13 at 18:46
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/");
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
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);
Red Boy
  • 5,429
  • 3
  • 28
  • 41
  • Thanks for taking the time to answer, but how is this different from the accepted answer? – Basic Apr 04 '18 at 09:18
  • 1
    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. – Red Boy Apr 04 '18 at 10:32
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;
    }
}
-2

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

 CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 HttpPost httpPostRequest = new HttpPost();
PAA
  • 1
  • 46
  • 174
  • 282