Come utilizzare java. net. URLConnection per attivare e gestire le richieste HTTP
Uso di java.net.URLConnection
viene chiesto abbastanza spesso qui, e il Oracle tutorial è troppo conciso su di esso.
Questo tutorial mostra fondamentalmente solo come attivare una richiesta GET e leggere la risposta. Non spiega da nessuna parte come usarlo per eseguire tra l'altro una richiesta POST, impostare le intestazioni delle richieste, leggere le intestazioni delle risposte, gestire i cookie, inviare un modulo HTML, caricare un file, ecc.
Quindi, come posso usare java.net.URLConnection
per attivare e gestire HTTP "avanzato" richieste?
11 answers
Prima un disclaimer in anticipo: i frammenti di codice pubblicati sono tutti esempi di base. Dovrai gestire banali IOException
s e RuntimeException
s come NullPointerException
, ArrayIndexOutOfBoundsException
e consorti te stesso.
Preparazione
Dobbiamo prima conoscere almeno l'URL e il set di caratteri. I parametri sono opzionali e dipendono dai requisiti funzionali.
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));
I parametri della query devono essere nel formato name=value
ed essere concatenati da &
. Si farebbe normalmente anche URL-encode i parametri della query con il set di caratteri specificato utilizzando URLEncoder#encode()
.
Il String#format()
è solo per comodità. Lo preferisco quando avrei bisogno dell'operatore di concatenazione delle stringhe +
più di due volte.
Attivazione di una richiesta HTTP GET con (facoltativamente) parametri di query
È un compito banale. È il metodo di richiesta predefinito.
URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...
Qualsiasi stringa di query deve essere concatenata all'URL utilizzando ?
. Il Accept-Charset
l'intestazione può suggerire al server in quale codifica si trovano i parametri. Se non si invia alcuna stringa di query, è possibile lasciare l'intestazione Accept-Charset
. Se non è necessario impostare alcuna intestazione, è anche possibile utilizzare URL#openStream()
metodo di scelta rapida.
InputStream response = new URL(url).openStream();
// ...
In entrambi i casi, se l'altro lato è un HttpServlet
, poi la sua doGet()
il metodo verrà chiamato e i parametri saranno disponibili da HttpServletRequest#getParameter()
.
Per il test per scopi, è possibile stampare il corpo della risposta su stdout come di seguito:
try (Scanner scanner = new Scanner(response)) {
String responseBody = scanner.useDelimiter("\\A").next();
System.out.println(responseBody);
}
Attivazione di una richiesta HTTP POST con parametri di query
Impostazione del URLConnection#setDoOutput()
a true
imposta implicitamente il metodo di richiesta su POST. Il POST HTTP standard come fanno i moduli Web è di tipo application/x-www-form-urlencoded
in cui la stringa di query viene scritta nel corpo della richiesta.
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();
// ...
Nota: ogni volta che si desidera inviare un modulo HTML a livello di codice, non dimenticare di prendere le coppie name=value
di qualsiasi <input type="hidden">
elementi nella stringa di query e, naturalmente, anche la coppia name=value
dell'elemento <input type="submit">
che si desidera "premere" a livello di codice (perché di solito è stato utilizzato nel lato server per distinguere se è stato premuto un pulsante e, in tal caso, quale).
Puoi anche lanciare il risultato ottenuto URLConnection
a HttpURLConnection
e usa il suo HttpURLConnection#setRequestMethod()
invece. Ma se stai cercando di utilizzare la connessione per l'output devi comunque impostare URLConnection#setDoOutput()
a true
.
HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
httpConnection.setRequestMethod("POST");
// ...
In entrambi i casi, se l'altro lato è un HttpServlet
, poi la sua doPost()
il metodo verrà chiamato e i parametri saranno disponibili da HttpServletRequest#getParameter()
.
Attiva effettivamente la richiesta HTTP
È possibile attivare esplicitamente la richiesta HTTP con URLConnection#connect()
, ma la richiesta verrà automaticamente attivata su richiesta quando si desidera ottenere informazioni sulla risposta HTTP, ad esempio il corpo della risposta utilizzando URLConnection#getInputStream()
e così via. Gli esempi precedenti fanno esattamente questo, quindi la chiamata connect()
è in realtà superflua.
Raccolta di informazioni sulla risposta HTTP
-
Hai bisogno di un
HttpURLConnection
tieni. Lanciare prima se necessario.int status = httpConnection.getResponseCode();
-
Intestazioni di risposta HTTP:
for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) { System.out.println(header.getKey() + "=" + header.getValue()); }
-
Quando il
Content-Type
contiene un parametrocharset
, quindi il corpo della risposta è probabilmente basato sul testo e vorremmo elaborare il corpo della risposta con la codifica dei caratteri specificata sul lato server.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. }
Mantenimento della sessione
La sessione lato server è solitamente supportata da un cookie. Alcuni moduli Web richiedono che tu abbia effettuato l'accesso e/o che tu sia monitorato da una sessione. È possibile utilizzare il CookieHandler
API per mantenere i cookie. È necessario preparare un CookieManager
con un CookiePolicy
di ACCEPT_ALL
prima di inviare tutte le richieste 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();
// ...
Si noti che questo è noto per non funzionare sempre correttamente in tutte le circostanze. Se fallisce per te, allora la cosa migliore è raccogliere e impostare manualmente le intestazioni dei cookie. Fondamentalmente è necessario afferrare tutte le intestazioni Set-Cookie
dalla risposta del login o dalla prima richiesta GET
e quindi passare attraverso le richieste successive.
// 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]);
}
// ...
Il {[61] } è lì per sbarazzarsi degli attributi dei cookie che sono irrilevante per il lato server come expires
, path
, ecc. In alternativa, puoi anche usare cookie.substring(0, cookie.indexOf(';'))
invece di split()
.
Modalità streaming
Il HttpURLConnection
per impostazione predefinita buffer l'intero corpo della richiesta prima di inviarlo effettivamente, indipendentemente dal fatto che tu abbia impostato una lunghezza di contenuto fissa usando connection.setRequestProperty("Content-Length", contentLength);
. Ciò può causare OutOfMemoryException
s ogni volta che si inviano contemporaneamente richieste POST di grandi dimensioni (ad esempio il caricamento di file). Per evitare questo, si desidera impostare il HttpURLConnection#setFixedLengthStreamingMode()
.
httpConnection.setFixedLengthStreamingMode(contentLength);
Ma se la lunghezza del contenuto non è nota in anticipo, è possibile utilizzare la modalità di streaming chunked impostando HttpURLConnection#setChunkedStreamingMode()
di conseguenza. Questo imposterà il HTTP Transfer-Encoding
intestazione a chunked
che costringerà il corpo della richiesta a essere inviato in blocchi. L'esempio seguente invierà il corpo in blocchi di 1KB.
httpConnection.setChunkedStreamingMode(1024);
User-Agent
Può accadere che una richiesta restituisca una risposta inaspettata, mentre funziona bene con un vero browser web. Il lato server sta probabilmente bloccando le richieste in base al User-Agent
intestazione richiesta. Il URLConnection
per impostazione predefinita lo imposterà su Java/1.6.0_19
dove l'ultima parte è ovviamente la versione JRE. È possibile ignorare questo come segue:
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.
Utilizzare la stringa User-Agent da un browser recente.
Gestione degli errori
Se il codice di risposta HTTP è 4nn
(Errore del client) o 5nn
(errore del server), è possibile vuoi leggere HttpURLConnection#getErrorStream()
per vedere se il server ha inviato informazioni di errore utili.
InputStream error = ((HttpURLConnection) connection).getErrorStream();
Se il codice di risposta HTTP è -1, qualcosa è andato storto con la gestione della connessione e della risposta. L'implementazione HttpURLConnection
è in JRE più vecchi un po ' bacata con il mantenimento delle connessioni in vita. È possibile disattivarlo impostando la proprietà di sistema http.keepAlive
su false
. Puoi farlo a livello di codice all'inizio della tua applicazione:
System.setProperty("http.keepAlive", "false");
Caricamento file
Useresti normalmente multipart/form-data
codifica per contenuti POST misti (dati binari e caratteri). La codifica è descritta in modo più dettagliato in 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();
}
Se l'altro lato è un HttpServlet
, poi la sua doPost()
il metodo sarà chiamato e le parti saranno disponibili da HttpServletRequest#getPart()
(nota, quindi non getParameter()
e così via!). Il metodo getPart()
è tuttavia relativamente nuovo, è introdotto in Servlet 3.0 (Glassfish 3, Tomcat 7, ecc). Prima di Servlet 3.0, la scelta migliore è utilizzare Apache Commons FileUpload per analizzare una richiesta multipart/form-data
. Vedi anche questa risposta per esempi di entrambi gli approcci FileUpload e Servelt 3.0.
Gestione di siti HTTPS non attendibili o configurati in modo errato
A volte è necessario collegare un URL HTTPS, forse perché si sta scrivendo un raschietto web. In tal caso, potresti probabilmente affrontare un {[89] } su alcuni siti HTTPS che non mantiene i loro certificati SSL aggiornati o java.security.cert.CertificateException: No subject alternative DNS name matching [hostname] found
o javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name
su alcuni siti HTTPS configurati in modo errato.
Il seguente inizializzatore di una volta static
nella classe web scraper dovrebbe rendere HttpsURLConnection
più indulgente nei confronti di quei siti HTTPS e quindi non gettare più quelle eccezioni.
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);
}
}
Ultime parole
Il Apache HttpComponents HttpClient è molto più conveniente in tutto questo:)
Analisi ed estrazione di HTML
Se tutto quello che vuoi è analizzare ed estrarre dati da HTML, allora meglio usare un parser HTML come Jsoup
Quando si lavora con HTTP è quasi sempre più utile fare riferimento a HttpURLConnection
piuttosto che alla classe base URLConnection
(poiché URLConnection
è una classe astratta quando si chiede URLConnection.openConnection()
su un URL HTTP che è ciò che si otterrà comunque).
Quindi puoi invece di affidarti a URLConnection#setDoOutput(true)
per impostare implicitamente il metodo di richiesta su POST invece di fare httpURLConnection.setRequestMethod("POST")
che alcuni potrebbero trovare più naturale (e che consente anche di specificare altri metodi di richiesta come PUT, SOPPRIMERE , ...).
Fornisce anche costanti HTTP utili in modo da poter fare:
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
Ispirato da questa e da altre domande su SO, ho creato un open source minimo basic-http-client che incarna la maggior parte delle tecniche trovate qui.
Google-http-java-client è anche una grande risorsa open source.
Ci sono 2 opzioni che puoi andare con gli accessi URL HTTP: GET / POST
OTTIENI richiesta:-
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()));
Richiesta POST: -
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()));
Ti suggerisco di dare un'occhiata al codice su kevinsawicki/http-request, è fondamentalmente un wrapper sopra HttpUrlConnection
fornisce un'API molto più semplice nel caso in cui tu voglia solo fare le richieste in questo momento o puoi dare un'occhiata alle fonti (non è troppo grande) per dare un'occhiata a come vengono gestite le connessioni.
Esempio: Fare una richiesta GET
con il tipo di contenuto application/json
e alcuni parametri di query:
// 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);
Sono stato anche molto ispirato da questa risposta.
Sono spesso su progetti in cui ho bisogno di fare un po ' di HTTP, e potrei non voler portare molte dipendenze di 3rd party (che portano altri e così via e così via, ecc.)
Ho iniziato a scrivere le mie utility in base ad alcune di questa conversazione (non nessuna dove fatto):
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 {
Quindi ci sono solo un gruppo o metodi statici.
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;
}
}
Quindi pubblica...
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;
}
Bene si ottiene l'idea....
Ecco i prove:
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);
}
Puoi trovare il resto qui:
Https://github.com/RichardHightower/boon
Il mio obiettivo è quello di fornire le cose comuni che si vorrebbe fare in un modo un po ' più semplice allora....
Aggiornare
Il nuovo client HTTP fornito con Java 9 ma come parte di un Modulo incubatore denominato
jdk.incubator.httpclient
. I moduli incubatori sono un mezzo per mettere le API non finali nelle mani degli sviluppatori mentre il Le API progrediscono verso la finalizzazione o la rimozione in un futuro rilasciare.
In Java 9, è possibile inviare una richiesta GET
come:
// GET
HttpResponse response = HttpRequest
.create(new URI("http://www.stackoverflow.com"))
.headers("Foo", "foovalue", "Bar", "barvalue")
.GET()
.response();
Quindi puoi esaminare il HttpResponse
restituito:
int statusCode = response.statusCode();
String responseBody = response.body(HttpResponse.asString());
Poiché questo nuovo client HTTP è in modulo java.httpclient
jdk.incubator.httpclient
, dovresti dichiarare questa dipendenza nel tuo file module-info.java
:
module com.foo.bar {
requires jdk.incubator.httpclient;
}
Inizialmente sono stato ingannato da questo articolo che favorisce HttpClient
.
Più tardi mi sono reso conto che {[1] } rimarrà da questo articolo
Come per il blog di Google:
Il client HTTP Apache ha meno bug su Eclair e Froyo. È la scelta migliore per queste versioni. Per il pan di zenzero , HttpURLConnection è la scelta migliore. La sua API semplice e di piccole dimensioni lo rende ideale per Android.
Compressione trasparente e caching di risposta ridurre l'uso della rete, migliorare la velocità e risparmiare la batteria. Le nuove applicazioni dovrebbero utilizzare HttpURLConnection; è dove spenderemo le nostre energie andando avanti.
Dopo aver letto questo articolo e alcune altre domande di stack over flow, sono convinto che HttpURLConnection
rimarrà per durate più lunghe.
Alcune delle domande della SE che favoriscono HttpURLConnections
:
Puoi anche usare JdkRequest
da jcabi-http (sono uno sviluppatore), che fa tutto questo lavoro per te, decorando HttpURLConnection, attivando richieste HTTP e analizzando le risposte, ad esempio:
String html = new JdkRequest("http://www.google.com").fetch().body();
Controlla questo post del blog per maggiori informazioni: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html
C'è anche OkHttp , che è un client HTTP efficiente per impostazione predefinita:
- Il supporto HTTP/2 consente a tutte le richieste allo stesso host di condividere un socket.
- Il pool di connessioni riduce la latenza della richiesta (se HTTP/2 non è disponibile).
- GZIP trasparente riduce le dimensioni del download.
- Il caching delle risposte evita completamente la rete per le richieste ripetute.
Creare prima un'istanza di OkHttpClient
:
OkHttpClient client = new OkHttpClient();
Quindi, prepara la tua richiesta GET
:
Request request = new Request.Builder()
.url(url)
.build();
Infine, usa OkHttpClient
per inviare Request
preparato:
Response response = client.newCall(request).execute();
Per maggiori dettagli, è possibile consultare la documentazione di OkHttp
Se si utilizza http get rimuovere questa riga
urlConnection.setDoOutput(true);