Вопрос: Как использовать java.net.URLConnection для запуска и обработки HTTP-запросов


Использование java.net.URLConnectionчасто спрашивают здесь, и Учебник Oracle является слишком Кратко об этом.

Этот учебник в основном показывает только, как запускать запрос GET и читать ответ. Он нигде не объясняет, как использовать его, среди прочих, выполнять POST-запрос, устанавливать заголовки запросов, читать заголовки ответов, обрабатывать файлы cookie, отправлять HTML-форму, загружать файл и т. Д.

Итак, как я могу использовать java.net.URLConnectionдля запуска и обработки «расширенных» HTTP-запросов?


1746


источник


Ответы:


Прежде всего, отказ от ответственности: опубликованные фрагменты кода являются основными примерами. Вам нужно будет обрабатывать тривиальные IOExceptionс и RuntimeExceptionкак NullPointerException, ArrayIndexOutOfBoundsExceptionи ссоритесь.


Подготовка

Сначала нам нужно знать хотя бы URL и кодировку. Параметры являются необязательными и зависят от функциональных требований.

String url = "http://example.com";
String charset = "UTF-8";  // Or in Java 7 and later, use the constant: java.nio.charset.StandardCharsets.UTF_8.name()
String param1 = "value1";
String param2 = "value2";
// ...

String query = String.format("param1=%s&param2=%s", 
     URLEncoder.encode(param1, charset), 
     URLEncoder.encode(param2, charset));

Параметры запроса должны быть в name=valueформате и быть объединены &, Вы, как правило, также URL-кодирование параметры запроса с указанной кодировкой, используя URLEncoder#encode(),

String#format()просто для удобства. Я предпочитаю, когда мне понадобится оператор конкатенации строк +более чем в два раза.


Увольнение HTTP GET запрос с (необязательно) параметрами запроса

Это тривиальная задача. Это метод запроса по умолчанию.

URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...

Любая строка запроса должна быть объединена с URL-адресом, используя ?, Accept-Charsetзаголовок может подсказывать серверу, в какой кодировке находятся параметры. Если вы не отправляете строку запроса, вы можете оставить Accept-Charsetзаголовок. Если вам не нужно устанавливать какие-либо заголовки, вы можете даже использовать URL#openStream()ярлык метод.

InputStream response = new URL(url).openStream();
// ...

В любом случае, если другая сторона HttpServlet, то его doGet()метод будет вызываться, и параметры будут доступны HttpServletRequest#getParameter(),

Для целей тестирования вы можете напечатать тело ответа на stdout, как показано ниже:

try (Scanner scanner = new Scanner(response)) {
    String responseBody = scanner.useDelimiter("\\A").next();
    System.out.println(responseBody);
}

Увольнение HTTP POST запрос с параметрами запроса

Настройка URLConnection#setDoOutput()в trueнеявно устанавливает метод запроса в POST. Стандартный HTTP POST в виде веб-форм имеет тип application/x-www-form-urlencodedв котором строка запроса записывается в тело запроса.

URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);

try (OutputStream output = connection.getOutputStream()) {
    output.write(query.getBytes(charset));
}

InputStream response = connection.getInputStream();
// ...

Примечание: всякий раз, когда вы хотите программно представить HTML-форму, не забудьте взять name=valueпары любых <input type="hidden">элементов в строку запроса и, конечно, также name=valueпара <input type="submit">элемент, который вы хотите «нажимать» программно (потому что это обычно используется на стороне сервера, чтобы различать, была ли нажата кнопка, и если да, то какая).

Вы также можете URLConnectionв HttpURLConnectionи использовать его HttpURLConnection#setRequestMethod()вместо. Но если вы пытаетесь использовать соединение для вывода, вам все равно нужно установить URLConnection#setDoOutput()в true,

HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
httpConnection.setRequestMethod("POST");
// ...

В любом случае, если другая сторона HttpServlet, то его doPost()метод будет вызываться, и параметры будут доступны HttpServletRequest#getParameter(),


Фактически, запуск запроса HTTP

Вы можете явно запустить HTTP-запрос с помощью URLConnection#connect(), но запрос будет автоматически запущен по требованию, когда вы захотите получить любую информацию об ответе HTTP, например, тело ответа, используя URLConnection#getInputStream()и так далее. Вышеприведенные примеры делают именно это, поэтому connect()звонок на самом деле лишний.


Сбор информации об ответах HTTP

  1. Статус ответа HTTP :

    Тебе необходимо HttpURLConnectionВот. Если это необходимо, сначала запустите его.

    int status = httpConnection.getResponseCode();
    
  2. Заголовки ответов HTTP :

    for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
        System.out.println(header.getKey() + "=" + header.getValue());
    }
    
  3. HTTP-кодирование :

    Когда Content-Typeсодержит charsetпараметр, тогда тело ответа, скорее всего, основано на тексте, и мы хотели бы обработать тело ответа с указанной кодировкой символов на стороне сервера.

    String contentType = connection.getHeaderField("Content-Type");
    String charset = null;
    
    for (String param : contentType.replace(" ", "").split(";")) {
        if (param.startsWith("charset=")) {
            charset = param.split("=", 2)[1];
            break;
        }
    }
    
    if (charset != null) {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(response, charset))) {
            for (String line; (line = reader.readLine()) != null;) {
                // ... System.out.println(line) ?
            }
        }
    } else {
        // It's likely binary content, use InputStream/OutputStream.
    }
    

Поддержание сеанса

Сеанс на стороне сервера обычно поддерживается файлом cookie. Некоторые веб-формы требуют, чтобы вы вошли в систему и / или отслеживались сеансом. Вы можете использовать CookieHandlerAPI для поддержки файлов cookie. Вам необходимо подготовить CookieManagerс CookiePolicyиз ACCEPT_ALLперед отправкой всех HTTP-запросов.

// First set the default cookie manager.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

// All the following subsequent URLConnections will use the same cookie manager.
URLConnection connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

Обратите внимание, что это, как известно, не всегда работает должным образом при любых обстоятельствах. Если вам это не удается, лучше всего вручную собрать и установить заголовки файлов cookie. Вам в основном нужно захватить все Set-Cookieзаголовки от ответа логина или первого GETзапрос, а затем передать это через последующие запросы.

// Gather all cookies on the first request.
URLConnection connection = new URL(url).openConnection();
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
// ...

// Then use the same cookies on all subsequent requests.
connection = new URL(url).openConnection();
for (String cookie : cookies) {
    connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
}
// ...

split(";", 2)[0]чтобы избавиться от атрибутов cookie, которые не имеют отношения к серверной стороне, например expires, path, и т. д. В качестве альтернативы вы также можете использовать cookie.substring(0, cookie.indexOf(';'))вместо split(),


Режим потоковой передачи

HttpURLConnectionбудет по умолчанию буфером все запросить тело до его фактической отправки, независимо от того, вы сами установили фиксированную длину контента, используя connection.setRequestProperty("Content-Length", contentLength);, Это может вызвать OutOfMemoryExceptionкогда вы одновременно отправляете большие POST-запросы (например, загружаете файлы). Чтобы этого избежать, вы хотите установить HttpURLConnection#setFixedLengthStreamingMode(),

httpConnection.setFixedLengthStreamingMode(contentLength);

Но если длина контента на самом деле неизвестна заранее, вы можете использовать режим потокового воспроизведения, установив HttpURLConnection#setChunkedStreamingMode()соответственно. Это установит HTTP Transfer-Encodingзаголовок chunkedкоторый заставит тело запроса отправляться в куски. Следующий пример отправит тело в куски 1 КБ.

httpConnection.setChunkedStreamingMode(1024);

User-Agent

Может случиться так, что запрос возвращает неожиданный ответ, в то время как он отлично работает с реальным веб-браузером. Вероятно, серверная сторона блокирует запросы на основе User-Agentзаголовок запроса. URLConnectionбудет по умолчанию устанавливать его на Java/1.6.0_19где последняя часть, очевидно, является версией JRE. Вы можете переопределить это следующим образом:

connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); // Do as if you're using Chrome 41 on Windows 7.

Используйте строку User-Agent из последний браузер ,


Обработка ошибок

Если код ответа HTTP 4nn(Ошибка клиента) или 5nn(Ошибка сервера), тогда вы можете прочитать HttpURLConnection#getErrorStream()чтобы узнать, отправил ли сервер какую-либо полезную информацию об ошибке.

InputStream error = ((HttpURLConnection) connection).getErrorStream();

Если код ответа HTTP равен -1, то что-то пошло не так с обработкой соединения и ответа. HttpURLConnectionреализация в старых JREs несколько затруднительна с сохранением связей. Вы можете отключить его, установив http.keepAliveсистемного свойства false, Вы можете сделать это программно в начале своего приложения:

System.setProperty("http.keepAlive", "false");

Загрузка файлов

Вы обычно используете multipart/form-dataкодирование смешанного содержимого POST (двоичные и символьные данные). Более подробно кодирование описано в RFC2388 ,

String param = "value";
File textFile = new File("/path/to/file.txt");
File binaryFile = new File("/path/to/file.bin");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

try (
    OutputStream output = connection.getOutputStream();
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
) {
    // Send normal param.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
    writer.append(CRLF).append(param).append(CRLF).flush();

    // Send text file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"textFile\"; filename=\"" + textFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); // Text file itself must be saved in this charset!
    writer.append(CRLF).flush();
    Files.copy(textFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // Send binary file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName())).append(CRLF);
    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    writer.append(CRLF).flush();
    Files.copy(binaryFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // End of multipart/form-data.
    writer.append("--" + boundary + "--").append(CRLF).flush();
}

Если другая сторона HttpServlet, то его doPost()метод будет вызываться, и части будут доступны HttpServletRequest#getPart()(обратите внимание, таким образом не getParameter()и так далее!). getPart()метод, однако, является относительно новым, он представлен в Servlet 3.0 (Glassfish 3, Tomcat 7 и т. д.). До сервлета 3.0 ваш лучший выбор Apache Commons FileUpload разобрать multipart/form-dataзапрос. Также см этот ответ для примеров подходов FileUpload и Servlet 3.0.


Работа с ненадежными или неправильно сконфигурированными сайтами HTTPS

Иногда вам нужно подключить URL HTTPS, возможно, потому, что вы пишете веб-скребок. В этом случае вы, вероятно, столкнетесь с javax.net.ssl.SSLException: Not trusted server certificateна некоторых сайтах HTTPS, которые не обновляют свои SSL-сертификаты, или java.security.cert.CertificateException: No subject alternative DNS name matching [hostname] foundили javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_nameна некоторых неправильно сконфигурированных сайтах HTTPS.

Следующие одноразовые staticИнициализатор в вашем классе веб-скребок должен сделать HttpsURLConnectionболее мягким относительно тех сайтов HTTPS и, следовательно, больше не бросать эти исключения.

static {
    TrustManager[] trustAllCertificates = new TrustManager[] {
        new X509TrustManager() {
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null; // Not relevant.
            }
            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
        }
    };

    HostnameVerifier trustAllHostnames = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true; // Just allow them all.
        }
    };

    try {
        System.setProperty("jsse.enableSNIExtension", "false");
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCertificates, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(trustAllHostnames);
    }
    catch (GeneralSecurityException e) {
        throw new ExceptionInInitializerError(e);
    }
}

Последние слова

Apache HttpComponents HttpClient является много более удобно в этом все :)


Анализ и извлечение HTML

Если все, что вам нужно, это разбор и извлечение данных из HTML, тогда лучше использовать HTML-парсер, например Jsoup


2510



При работе с HTTP почти всегда полезно ссылаться на HttpURLConnectionа не базовый класс URLConnection(поскольку URLConnectionявляется абстрактным классом, когда вы просите URLConnection.openConnection()по URL-адресу HTTP, это то, что вы получите в любом случае).

Тогда вы можете вместо того, чтобы полагаться на URLConnection#setDoOutput(true)для неявного задания метода запроса ПОСЛЕ вместо этого httpURLConnection.setRequestMethod("POST")которые некоторые могут найти более естественными (и которые также позволяют указывать другие методы запроса, такие как ПОЛОЖИЛ , УДАЛИТЬ , ...).

Он также предоставляет полезные HTTP-константы, чтобы вы могли:

int responseCode = httpURLConnection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {

80



Вдохновленный этим и другими вопросами о SO, я создал минимальный открытый исходный код базовый HTTP-клиент который воплощает большинство методов, найденных здесь.

Google-HTTP-Java-клиент также является отличным ресурсом с открытым исходным кодом.


47



There are 2 options you can go with HTTP URL Hits : GET / POST

GET Request :-

HttpURLConnection.setFollowRedirects(true); // defaults to true

String url = "https://name_of_the_url";
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
System.out.println(String.valueOf(http_conn.getResponseCode()));

POST request :-

HttpURLConnection.setFollowRedirects(true); // defaults to true

String url = "https://name_of_the_url"
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
http_conn.setDoOutput(true);
PrintWriter out = new PrintWriter(http_conn.getOutputStream());
if (urlparameter != null) {
   out.println(urlparameter);
}
out.close();
out = null;
System.out.println(String.valueOf(http_conn.getResponseCode()));

20



I suggest you take a look at the code on kevinsawicki/http-request, its basically a wrapper on top of HttpUrlConnection it provides a much simpler API in case you just want to make the requests right now or you can take a look at the sources (it's not too big) to take a look at how connections are handled.

Example: Make a GET request with content type application/json and some query parameters:

// GET http://google.com?q=baseball%20gloves&size=100
String response = HttpRequest.get("http://google.com", true, "q", "baseball gloves", "size", 100)
        .accept("application/json")
        .body();
System.out.println("Response was: " + response);

18



I was also very inspired by this response.

I am often on projects where I need to do some HTTP, and I may not want to bring in a lot of 3rd party dependencies (which bring in others and so on and so on, etc.)

I started to write my own utilities based on some of this conversation (not any where done):

package org.boon.utils;


import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;

import static org.boon.utils.IO.read;

public class HTTP {

Then there are just a bunch or static methods.

public static String get(
        final String url) {

    Exceptions.tryIt(() -> {
        URLConnection connection;
        connection = doGet(url, null, null, null);
        return extractResponseString(connection);
    });
    return null;
}

public static String getWithHeaders(
        final String url,
        final Map<String, ? extends Object> headers) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, null, null);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

public static String getWithContentType(
        final String url,
        final Map<String, ? extends Object> headers,
        String contentType) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, contentType, null);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}
public static String getWithCharSet(
        final String url,
        final Map<String, ? extends Object> headers,
        String contentType,
        String charSet) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, contentType, charSet);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

Then post...

public static String postBody(
        final String url,
        final String body) {
    URLConnection connection;
    try {
        connection = doPost(url, null, "text/plain", null, body);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

public static String postBodyWithHeaders(
        final String url,
        final Map<String, ? extends Object> headers,
        final String body) {
    URLConnection connection;
    try {
        connection = doPost(url, headers, "text/plain", null, body);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}



public static String postBodyWithContentType(
        final String url,
        final Map<String, ? extends Object> headers,
        final String contentType,
        final String body) {

    URLConnection connection;
    try {
        connection = doPost(url, headers, contentType, null, body);


        return extractResponseString(connection);


    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }


}


public static String postBodyWithCharset(
        final String url,
        final Map<String, ? extends Object> headers,
        final String contentType,
        final String charSet,
        final String body) {

    URLConnection connection;
    try {
        connection = doPost(url, headers, contentType, charSet, body);


        return extractResponseString(connection);


    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }


}

private static URLConnection doPost(String url, Map<String, ? extends Object> headers,
                                    String contentType, String charset, String body
                                    ) throws IOException {
    URLConnection connection;/* Handle output. */
    connection = new URL(url).openConnection();
    connection.setDoOutput(true);
    manageContentTypeHeaders(contentType, charset, connection);

    manageHeaders(headers, connection);


    IO.write(connection.getOutputStream(), body, IO.CHARSET);
    return connection;
}

private static void manageHeaders(Map<String, ? extends Object> headers, URLConnection connection) {
    if (headers != null) {
        for (Map.Entry<String, ? extends Object> entry : headers.entrySet()) {
            connection.setRequestProperty(entry.getKey(), entry.getValue().toString());
        }
    }
}

private static void manageContentTypeHeaders(String contentType, String charset, URLConnection connection) {
    connection.setRequestProperty("Accept-Charset", charset == null ? IO.CHARSET : charset);
    if (contentType!=null && !contentType.isEmpty()) {
        connection.setRequestProperty("Content-Type", contentType);
    }
}

private static URLConnection doGet(String url, Map<String, ? extends Object> headers,
                                    String contentType, String charset) throws IOException {
    URLConnection connection;/* Handle output. */
    connection = new URL(url).openConnection();
    manageContentTypeHeaders(contentType, charset, connection);

    manageHeaders(headers, connection);

    return connection;
}

private static String extractResponseString(URLConnection connection) throws IOException {
/* Handle input. */
    HttpURLConnection http = (HttpURLConnection)connection;
    int status = http.getResponseCode();
    String charset = getCharset(connection.getHeaderField("Content-Type"));

    if (status==200) {
        return readResponseBody(http, charset);
    } else {
        return readErrorResponseBody(http, status, charset);
    }
}

private static String readErrorResponseBody(HttpURLConnection http, int status, String charset) {
    InputStream errorStream = http.getErrorStream();
    if ( errorStream!=null ) {
        String error = charset== null ? read( errorStream ) :
            read( errorStream, charset );
        throw new RuntimeException("STATUS CODE =" + status + "\n\n" + error);
    } else {
        throw new RuntimeException("STATUS CODE =" + status);
    }
}

private static String readResponseBody(HttpURLConnection http, String charset) throws IOException {
    if (charset != null) {
        return read(http.getInputStream(), charset);
    } else {
        return read(http.getInputStream());
    }
}

private static String getCharset(String contentType) {
    if (contentType==null)  {
        return null;
    }
    String charset = null;
    for (String param : contentType.replace(" ", "").split(";")) {
        if (param.startsWith("charset=")) {
            charset = param.split("=", 2)[1];
            break;
        }
    }
    charset = charset == null ?  IO.CHARSET : charset;

    return charset;
}

Well you get the idea....

Here are the tests:

static class MyHandler implements HttpHandler {
    public void handle(HttpExchange t) throws IOException {

        InputStream requestBody = t.getRequestBody();
        String body = IO.read(requestBody);
        Headers requestHeaders = t.getRequestHeaders();
        body = body + "\n" + copy(requestHeaders).toString();
        t.sendResponseHeaders(200, body.length());
        OutputStream os = t.getResponseBody();
        os.write(body.getBytes());
        os.close();
    }
}


@Test
public void testHappy() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9212), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBodyWithContentType("http://localhost:9212/test", headers, "text/plain", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));


    response = HTTP.postBodyWithCharset("http://localhost:9212/test", headers, "text/plain", "UTF-8", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    response = HTTP.postBodyWithHeaders("http://localhost:9212/test", headers, "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));


    response = HTTP.get("http://localhost:9212/test");

    System.out.println(response);


    response = HTTP.getWithHeaders("http://localhost:9212/test", headers);

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));



    response = HTTP.getWithContentType("http://localhost:9212/test", headers, "text/plain");

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));



    response = HTTP.getWithCharSet("http://localhost:9212/test", headers, "text/plain", "UTF-8");

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    Thread.sleep(10);

    server.stop(0);


}

@Test
public void testPostBody() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9220), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBody("http://localhost:9220/test", "hi mom");

    assertTrue(response.contains("hi mom"));


    Thread.sleep(10);

    server.stop(0);


}

@Test(expected = RuntimeException.class)
public void testSad() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9213), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBodyWithContentType("http://localhost:9213/foo", headers, "text/plain", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    Thread.sleep(10);

    server.stop(0);


}

You can find the rest here:

https://github.com/RichardHightower/boon

My goal is to provide the common things one would want to do in a bit more easier way then....


17



Update

The new HTTP Client shipped with Java 9 but as part of an Incubator module named jdk.incubator.httpclient. Incubator modules are a means of putting non-final APIs in the hands of developers while the APIs progress towards either finalization or removal in a future release.

In Java 9, you can send a GET request like:

// GET
HttpResponse response = HttpRequest
    .create(new URI("http://www.stackoverflow.com"))
    .headers("Foo", "foovalue", "Bar", "barvalue")
    .GET()
    .response();

Then you can examine the returned HttpResponse:

int statusCode = response.statusCode();
String responseBody = response.body(HttpResponse.asString());

Since this new HTTP Client is in java.httpclient jdk.incubator.httpclient module, you should declare this dependency in your module-info.java file:

module com.foo.bar {
    requires jdk.incubator.httpclient;
}

13



Initially I was misled by this article which favours HttpClient.

Later I have been realized that HttpURLConnection is going to stay from this article

As per the Google blog:

Apache HTTP client has fewer bugs on Eclair and Froyo. It is the best choice for these releases. For Gingerbread , HttpURLConnection is the best choice. Its simple API and small size makes it great fit for Android.

Transparent compression and response caching reduce network use, improve speed and save battery. New applications should use HttpURLConnection; it is where we will be spending our energy going forward.

After reading this article and some other stack over flow questions, I am convinced that HttpURLConnection is going to stay for longer durations.

Some of the SE questions favouring HttpURLConnections:

On Android, make a POST request with URL Encoded Form data without using UrlEncodedFormEntity

HttpPost works in Java project, not in Android


12



You can also use JdkRequest from jcabi-http (I'm a developer), which does all this work for you, decorating HttpURLConnection, firing HTTP requests and parsing responses, for example:

String html = new JdkRequest("http://www.google.com").fetch().body();

Check this blog post for more info: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html


9



There is also OkHttp, which is an HTTP client that’s efficient by default:

  • HTTP/2 support allows all requests to the same host to share a socket.
  • Connection pooling reduces request latency (if HTTP/2 isn’t available).
  • Transparent GZIP shrinks download sizes.
  • Response caching avoids the network completely for repeat requests.

First create an instance of OkHttpClient:

OkHttpClient client = new OkHttpClient();

Then, prepare your GET request:

Request request = new Request.Builder()
      .url(url)
      .build();

finally, use OkHttpClient to send prepared Request:

Response response = client.newCall(request).execute();

For more details, you can consult the OkHttp's documentation


9



if you are using http get please remove this line

urlConnection.setDoOutput(true);

8



I recomend http-request built on apache http api. (I'm a developer)

Perform HTTP GET request

static final HttpRequest<String> httpRequest =
     HttpRequestBuilder.createGet(someUri, String.class)
     .responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();

ResponseHandler<String> responseHandler = httpRequest.execute(requestParameters);

int statusCode = responseHandler.getStatusCode();
String responseBody = responseHandler.get(); // see javadoc of get method

or

 ResponseHandler<String> responseHandler = 
      httpRequest.executeWithQuery(queryString); //queryString example "param1=param1&param2=param2"

Perform HTTP POST request

Replace HttpRequestBuilder.createGet to HttpRequestBuilder.createPost

Add headers

static final HttpRequest<String> httpRequest =
      HttpRequestBuilder.createGet(someUri, String.class)
           .responseDeserializer(ResponseDeserializer.ignorableDeserializer())
           .addDefaultHeader("Accept", "application/json")
           .build();

Convert response to type

let's say response is JSON and you know it

{"name":"myname","lastname":"mylastname","age":25}

You must create class User:

public User{
    private String Name;
    private String Lastname;
    private int Age;

   // getters and setters
}

static final HttpRequest<User> httpRequest =
     HttpRequestBuilder.createGet(someUri, User.class).build();

ResponseHandler<User> responseHandler = httpRequest.execute(requestParameters);
User userFromResponse = responseHandler.orElse(null); //returns null if content isn't present
System.out.print(user.getName()); //myname

Note: You don't need to worry about Exceptions. All exceptions is wrapped.


-2