L'utilisation de Java.net.URLConnection
est posée assez souvent ici, et le tutoriel Oracle est aussi concis à ce sujet.
Fondamentalement, ce tutoriel montre uniquement comment déclencher une requête GET et lire la réponse. Cela n'explique nulle part comment l'utiliser pour effectuer, entre autres, une demande POST, définir des en-têtes de demande, lire des en-têtes de réponse, gérer les cookies, envoyer un formulaire HTML, télécharger un fichier, etc.
Alors, comment puis-je utiliser _Java.net.URLConnection
_ pour déclencher et gérer les requêtes HTTP "avancées"?
Tout d'abord, une clause de non-responsabilité: les extraits de code publiés sont tous des exemples élémentaires. Vous aurez besoin de manipuler des IOException
s et des RuntimeException
s triviaux comme NullPointerException
, ArrayIndexOutOfBoundsException
et vous complice.
Nous devons d’abord connaître au moins l’URL et le charset. Les paramètres sont facultatifs et dépendent des exigences fonctionnelles.
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¶m2=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(param2, charset));
Les paramètres de requête doivent être au format name=value
et être concaténés par &
. Normalement, vous devez également encoder les paramètres de la requête avec le jeu de caractères spécifié à l'aide de URLEncoder#encode()
.
La String#format()
est juste pour votre commodité. Je le préfère lorsque j'ai besoin de l'opérateur de concaténation de chaînes +
plus de deux fois.
C'est une tâche triviale. C'est la méthode de requête par défaut.
URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...
Toute chaîne de requête doit être concaténée à l'URL à l'aide de ?
. L'en-tête Accept-Charset
peut indiquer au serveur le codage des paramètres. Si vous n'envoyez aucune chaîne de requête, vous pouvez laisser l'en-tête Accept-Charset
. Si vous n'avez pas besoin de définir d'en-tête, vous pouvez même utiliser la méthode de raccourci URL#openStream()
.
InputStream response = new URL(url).openStream();
// ...
Quoi qu'il en soit, si l'autre côté est un HttpServlet
, sa méthode doGet()
sera appelée et les paramètres seront disponibles par HttpServletRequest#getParameter()
.
À des fins de test, vous pouvez imprimer le corps de la réponse sur stdout comme suit:
try (Scanner scanner = new Scanner(response)) {
String responseBody = scanner.useDelimiter("\\A").next();
System.out.println(responseBody);
}
La définition de URLConnection#setDoOutput()
sur true
définit implicitement la méthode de requête sur POST. Comme le font les formulaires Web, HTTP POST _ est de type application/x-www-form-urlencoded
dans lequel la chaîne de requête est écrite dans le corps de la requête.
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();
// ...
Remarque: lorsque vous souhaitez soumettre un formulaire HTML par programme, n'oubliez pas de prendre les paires name=value
de tous les éléments <input type="hidden">
dans la chaîne de requête et, bien sûr, également la paire name=value
de l'élément <input type="submit">
que vous souhaitez "appuyer, "par programmation (car cela a généralement été utilisé côté serveur pour distinguer si un bouton a été enfoncé et, le cas échéant, lequel).
Vous pouvez également convertir le résultat obtenu URLConnection
en HttpURLConnection
et utiliser sa fonction HttpURLConnection#setRequestMethod()
. Mais si vous essayez d'utiliser la connexion pour la sortie, vous devez toujours définir URLConnection#setDoOutput()
sur true
.
HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
httpConnection.setRequestMethod("POST");
// ...
Quoi qu'il en soit, si l'autre côté est un HttpServlet
, sa méthode doPost()
sera appelée et les paramètres seront disponibles par HttpServletRequest#getParameter()
.
Vous pouvez déclencher explicitement la requête HTTP avec URLConnection#connect()
, mais la requête sera automatiquement déclenchée à la demande lorsque vous souhaitez obtenir des informations sur la réponse HTTP, telles que le corps de la réponse utilisant URLConnection#getInputStream()
et ainsi de suite. C'est exactement ce que font les exemples ci-dessus, donc l'appel connect()
est en réalité superflu.
Vous avez besoin d'un HttpURLConnection
ici. Jetez-le d'abord si nécessaire.
int status = httpConnection.getResponseCode();
for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
System.out.println(header.getKey() + "=" + header.getValue());
}
Lorsque le Content-Type
contient un paramètre charset
, le corps de la réponse est probablement basé sur du texte et nous aimerions traiter le corps de la réponse avec le codage de caractères spécifié côté serveur.
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.
}
La session côté serveur est généralement accompagnée d'un cookie. Certains formulaires Web nécessitent que vous soyez connecté et/ou suivi par une session. Vous pouvez utiliser l'API CookieHandler
pour conserver les cookies. Vous devez préparer un CookieManager
avec un CookiePolicy
de ACCEPT_ALL
avant d'envoyer toutes les demandes 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();
// ...
Notez que cela est connu pour ne pas toujours fonctionner correctement dans toutes les circonstances. Si cela échoue pour vous, le mieux est de rassembler et de définir manuellement les en-têtes de cookie. Vous devez essentiellement extraire tous les en-têtes Set-Cookie
de la réponse de la connexion ou de la première demande GET
, puis les transmettre aux demandes suivantes.
// 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]);
}
// ...
La split(";", 2)[0]
permet de supprimer les attributs de cookie non pertinents pour le serveur, tels que expires
, path
, etc. Sinon, vous pouvez également utiliser cookie.substring(0, cookie.indexOf(';'))
au lieu de split()
.
Le HttpURLConnection
met par défaut en mémoire tampon le corps de la requête entière avant de l'envoyer, que vous ayez défini vous-même une longueur de contenu fixe à l'aide de connection.setRequestProperty("Content-Length", contentLength);
. Cela peut entraîner OutOfMemoryException
chaque fois que vous envoyez simultanément de grandes demandes POST (par exemple, le téléchargement de fichiers). Pour éviter cela, vous souhaitez définir la HttpURLConnection#setFixedLengthStreamingMode()
.
httpConnection.setFixedLengthStreamingMode(contentLength);
Mais si la longueur du contenu n’est pas vraiment connue au préalable, vous pouvez utiliser le mode de diffusion en bloc en définissant la fonction HttpURLConnection#setChunkedStreamingMode()
en conséquence. Cela définira l'en-tête HTTP Transfer-Encoding
sur chunked
, ce qui forcera le corps de la requête à être envoyé en morceaux. L'exemple ci-dessous enverra le corps en morceaux de 1 Ko.
httpConnection.setChunkedStreamingMode(1024);
Il peut arriver qu'une demande renvoie une réponse inattendue, alors que cela fonctionne correctement avec un navigateur Web réel . Le côté serveur bloque probablement les demandes en fonction de l'en-tête de demande User-Agent
. URLConnection
le définira par défaut sur Java/1.6.0_19
où la dernière partie est évidemment la version de JRE. Vous pouvez remplacer ceci comme suit:
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.
Utilisez la chaîne User-Agent d'un navigateur récent .
Si le code de réponse HTTP est 4nn
(erreur du client) ou 5nn
(erreur du serveur), vous pouvez lire la HttpURLConnection#getErrorStream()
pour voir si le serveur a envoyé des informations d'erreur utiles.
InputStream error = ((HttpURLConnection) connection).getErrorStream();
Si le code de réponse HTTP est -1, il y a eu un problème de connexion et de traitement des réponses. L'implémentation HttpURLConnection
dans les anciens JRE est quelque peu boguée avec le maintien des connexions actives. Vous pouvez le désactiver en définissant la propriété système http.keepAlive
sur false
. Vous pouvez le faire par programme au début de votre application en:
System.setProperty("http.keepAlive", "false");
Vous utiliseriez normalement multipart/form-data
un codage pour un contenu mixte POST (données binaires et caractères). Le codage est décrit plus en détail dans 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();
}
Si l'autre côté est un HttpServlet
, sa méthode doPost()
sera appelée et les pièces seront disponibles par HttpServletRequest#getPart()
(note, donc pas getParameter()
et ainsi de suite!). La méthode getPart()
est cependant relativement nouvelle, elle a été introduite dans Servlet 3.0 (Glassfish 3, Tomcat 7, etc.). Avant Servlet 3.0, votre meilleur choix consiste à utiliser Apache Commons FileUpload pour analyser une requête multipart/form-data
. Voir aussi cette réponse pour des exemples d'approches FileUpload et Servelt 3.0.
Parfois, vous devez connecter une URL HTTPS, peut-être parce que vous écrivez un scraper Web. Dans ce cas, il est possible que vous rencontriez un javax.net.ssl.SSLException: Not trusted server certificate
sur certains sites HTTPS qui ne maintient pas leurs certificats SSL à jour, ou un Java.security.cert.CertificateException: No subject alternative DNS name matching [hostname] found
ou javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name
sur certains sites HTTPS mal configurés.
L’initialiseur static
à exécution unique suivant de votre classe de nettoyage Web devrait rendre HttpsURLConnection
plus indulgent vis-à-vis de ces sites HTTPS et ainsi ne plus lancer ces exceptions.
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);
}
}
Le Apache HttpComponents HttpClient est beaucoup plus pratique dans tout cela :)
Si tout ce que vous voulez, c'est analyser et extraire des données à partir de HTML, utilisez plutôt un analyseur HTML tel que Jsoup
Lorsque vous travaillez avec HTTP, il est presque toujours plus utile de faire référence à HttpURLConnection
plutôt qu'à la classe de base URLConnection
(puisque URLConnection
est une classe abstraite lorsque vous demandez URLConnection.openConnection()
sur HTTP. URL c'est ce que vous obtiendrez quand même).
Ensuite, vous pouvez vous contenter de URLConnection#setDoOutput(true)
pour définir implicitement la méthode de requête sur POST à la place faire httpURLConnection.setRequestMethod("POST")
ce que certains pourraient trouver plus naturel (et qui vous permet également de spécifier d'autres méthodes de requête telles que PUT, DELETE, ...).
Il fournit également des constantes HTTP utiles pour que vous puissiez faire:
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
Inspiré par cette question et d’autres sur SO, j’ai créé un open source minimal basic-http-client , qui reprend la plupart des techniques décrites ici.
google-http-Java-client est également une excellente ressource open source.
Il y a 2 options possibles avec HTTP URL Hits: GET/POST
Demande GET: -
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 demande: -
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()));
Je vous suggère de jeter un coup d'oeil au code sur kevinsawicki/http-request , c'est fondamentalement un wrapper au-dessus de HttpUrlConnection
il fournit une API beaucoup plus simple au cas où vous voudriez simplement faire les demandes. maintenant ou vous pouvez regarder les sources (ce n'est pas trop gros) pour voir comment les connexions sont gérées.
Exemple: Faites une demande GET
avec le type de contenu application/json
et des paramètres de requête:
// 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);
Le nouveau client HTTP livré avec Java 9 mais faisant partie d'un module d'incubateur nommé
jdk.incubator.httpclient
. Les modules de l'incubateur sont un moyen de mettre des API non finales entre les mains des développeurs tandis que les API progressent vers la finalisation ou la suppression dans une version ultérieure.
Dans Java 9, vous pouvez envoyer une demande GET
comme:
// GET
HttpResponse response = HttpRequest
.create(new URI("http://www.stackoverflow.com"))
.headers("Foo", "foovalue", "Bar", "barvalue")
.GET()
.response();
Ensuite, vous pouvez examiner le HttpResponse
retourné:
int statusCode = response.statusCode();
String responseBody = response.body(HttpResponse.asString());
Depuis que ce nouveau client HTTP est en Module Java.httpclient
jdk.incubator.httpclient
, vous devez déclarer cette dépendance dans votre fichier module-info.Java
:
module com.foo.bar {
requires jdk.incubator.httpclient;
}
Cette réponse m'a également beaucoup inspirée.
Je suis souvent sur des projets où je dois utiliser un certain HTTP et je ne souhaite peut-être pas introduire beaucoup de dépendances de tiers (qui en amènent d'autres, etc., etc.).
J'ai commencé à écrire mes propres utilitaires sur la base d'une partie de cette conversation (pas du tout terminé):
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 {
Ensuite, il y a juste un tas ou des méthodes statiques.
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;
}
}
Puis postez ...
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;
}
Eh bien, vous avez l'idée ....
Voici les 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);
}
Vous pouvez trouver le reste ici:
https://github.com/RichardHightower/boon
Mon objectif est de fournir les choses communes que l'on voudrait faire un peu plus facilement, alors ...
Au début, j'ai été induit en erreur par ceci article qui favorise HttpClient
.
Plus tard, je me suis rendu compte que HttpURLConnection
va rester de cette article
Selon le blog de Google :
Le client HTTP Apache a moins de bugs sur Eclair et Froyo. C'est le meilleur choix pour ces versions. HttpURLConnection est le meilleur choix pour le pain d’épice. Son API simple et sa petite taille le rendent idéal pour Android.
La compression transparente et la mise en cache des réponses réduisent l'utilisation du réseau, améliorent la vitesse et économisent la batterie. Les nouvelles applications doivent utiliser HttpURLConnection; c'est là que nous dépenserons notre énergie pour aller de l'avant.
Après avoir lu cet article et quelques autres questions de débordement de pile, je suis convaincu que HttpURLConnection
restera plus longtemps.
Certaines des questions SE favorisant HttpURLConnections
:
Il existe également OkHttp , qui est un client HTTP efficace par défaut:
- La prise en charge HTTP/2 permet à toutes les demandes adressées au même hôte de partager un socket.
- Le regroupement de connexions réduit la latence des demandes (si HTTP/2 n’est pas disponible).
- GZIP transparent réduit la taille des téléchargements.
- La mise en cache des réponses évite complètement le réseau pour les demandes répétées.
Commencez par créer une instance de OkHttpClient
:
OkHttpClient client = new OkHttpClient();
Ensuite, préparez votre demande GET
:
Request request = new Request.Builder()
.url(url)
.build();
enfin, utilisez OkHttpClient
pour envoyer préparé Request
:
Response response = client.newCall(request).execute();
Pour plus de détails, vous pouvez consulter le documentation d'OkHttp
Vous pouvez également utiliser JdkRequest
à partir de jcabi-http (je suis un développeur), qui effectue tout ce travail pour vous: décorer HttpURLConnection, lancer des requêtes HTTP et analyser les réponses, pour exemple:
String html = new JdkRequest("http://www.google.com").fetch().body();
Consultez ce billet de blog pour plus d'informations: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html
si vous utilisez http get s'il vous plaît supprimer cette ligne
urlConnection.setDoOutput(true);