Java.net.URLConnection
の使用はここでかなり頻繁に聞かれます、そして Oracleチュートリアル は も それについて簡潔にします。
そのチュートリアルは基本的にGETリクエストを起動してレスポンスを読む方法を示すだけです。 POST要求の実行、要求ヘッダーの設定、応答ヘッダーの読み取り、Cookieの処理、HTMLフォームの送信、ファイルのアップロードなどに使用する方法については説明されていません。
それでは、どのようにしてJava.net.URLConnection
を使って「高度な」HTTPリクエストを起動し処理することができるのでしょうか。
まず免責事項:投稿されたコードスニペットはすべて基本的な例です。 IOException
、RuntimeException
のような些細なNullPointerException
sとArrayIndexOutOfBoundsException
sを処理する必要があります。
まず、少なくとも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¶m2=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(param2, charset));
クエリパラメータはname=value
形式であり、&
によって連結されている必要があります。通常、 URL-encodeURLEncoder#encode()
を使用して、指定された文字セットを持つクエリパラメータを使用します。
String#format()
は便宜上のものです。 String連結演算子+
が2回以上必要な場合に、この方法を好みます。
簡単な作業です。これがデフォルトのリクエスト方法です。
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()
によって使用可能になります。
テストのために、以下のように応答本文を標準出力に出力できます。
try (Scanner scanner = new Scanner(response)) {
String responseBody = scanner.useDelimiter("\\A").next();
System.out.println(responseBody);
}
URLConnection#setDoOutput()
をtrue
に設定すると、要求メソッドが暗黙的にPOSTに設定されます。 Webフォームが行う標準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()
によって使用可能になります。
URLConnection#connect()
を使用してHTTPリクエストを明示的に起動できますが、 URLConnection#getInputStream()
などを使用したレスポンス本文など、HTTPレスポンスに関する情報を取得する場合、リクエストは自動的にオンデマンドで起動されます。上記の例はまさにそれを行うので、connect()
呼び出しは実際には不要です。
ここで HttpURLConnection
が必要です。必要に応じて最初にキャストしてください。
int status = httpConnection.getResponseCode();
for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
System.out.println(header.getKey() + "=" + header.getValue());
}
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によってサポートされます。一部のWebフォームでは、ログインするか、セッションで追跡する必要があります。 CookieHandler
APIを使用して、Cookieを維持できます。すべてのHTTPリクエストを送信する前に、 CookieManager
of CookiePolicy
of ACCEPT_ALL
を準備する必要があります。
// 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ヘッダーを手動で収集して設定することをお勧めします。基本的に、ログインの応答または最初のGET
リクエストからすべてのSet-Cookie
ヘッダーを取得し、それを後続のリクエストに渡す必要があります。
// 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]
は、expires
、path
などのサーバー側に関係のないCookie属性を削除するためにあります。代わりに、cookie.substring(0, cookie.indexOf(';'))
の代わりにsplit()
を使用することもできます。
HttpURLConnection
は、デフォルトで entire 要求本文をバッファリングしてから、実際に送信する前に、connection.setRequestProperty("Content-Length", contentLength);
を使用して自分で固定コンテンツ長を設定したかどうかにかかわらず。これにより、大規模なPOSTリクエストを同時に送信する場合(ファイルのアップロードなど)にOutOfMemoryException
sが発生する可能性があります。これを回避するには、 HttpURLConnection#setFixedLengthStreamingMode()
を設定します。
httpConnection.setFixedLengthStreamingMode(contentLength);
ただし、コンテンツの長さが事前にわからない場合は、それに応じて HttpURLConnection#setChunkedStreamingMode()
を設定することにより、チャンクストリーミングモードを利用できます。これにより、HTTP Transfer-Encoding
ヘッダーがchunked
に設定されます。これにより、リクエストボディが強制的にチャンクで送信されます。以下の例は、1KBのチャンクで本文を送信します。
httpConnection.setChunkedStreamingMode(1024);
リクエストが予期しない応答を返す一方で、実際のWebブラウザでは正常に動作することがあります 。サーバー側はおそらく、 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
実装は古いJREにあり、接続を維持するのに多少バグがあります。 http.keepAlive
システムプロパティをfalse
に設定することで、この機能をオフにすることができます。これは、アプリケーションの最初に次の方法でプログラムで実行できます。
System.setProperty("http.keepAlive", "false");
通常、混合POSTコンテンツ(バイナリデータと文字データ)に multipart/form-data
エンコーディングを使用します。エンコードの詳細については、 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()
によってパーツが使用可能になります(したがって、notgetParameter()
など!)。ただし、getPart()
メソッドは比較的新しく、Servlet 3.0(Glassfish 3、Tomcat 7など)で導入されました。 Servlet 3.0以前では、 Apache Commons FileUpload を使用してmultipart/form-data
リクエストを解析するのが最良の選択です。 FileUploadとServelt 3.0の両方のアプローチの例については、 この回答 も参照してください。
おそらくWebスクレーパーを作成しているため、HTTPS URLを接続する必要がある場合があります。その場合、SSL証明書を最新に保っていないHTTPSサイトでjavax.net.ssl.SSLException: Not trusted server certificate
に直面するか、誤って設定されたHTTPSサイトでJava.security.cert.CertificateException: No subject alternative DNS name matching [hostname] found
またはjavax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name
に直面する可能性があります。
Webスクレイパークラスの次の1回限りの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 は much より便利です:)
解析してHTMLからデータを抽出するだけであれば、 Jsoup のようなHTMLパーサーを使用した方が良い
HTTPを扱うときは、基本クラスのHttpURLConnection
ではなくURLConnection
を参照するほうがほとんどの場合より便利です(URLConnection
はHTTP URLでURLConnection.openConnection()
を要求した場合の抽象クラスなので、どちらにしても戻ります)。
その場合、URLConnection#setDoOutput(true)
に頼って暗黙のうちにリクエストメソッドをPOSTに設定する代わりにhttpURLConnection.setRequestMethod("POST")
を実行することもできます(これにより、より自然なものもあります(これによりPUT、DELETE、...)。
また、便利なHTTP定数も用意されているので、次のことが可能です。
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
SOに関するこれと他の質問に触発されて、私は最小のオープンソースを作成しました basic-http-client ここで見つけられるテクニックのほとんどを具体化します。
google-http-Java-client も素晴らしいオープンソースのリソースです。
HTTP URL Hitsには2つの選択肢があります:GET/POST
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リクエスト: -
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()));
kevinsawicki/http-request のコードを見てみることをお勧めします。基本的にはHttpUrlConnection
の上にあるラッパーで、今すぐリクエストをしたい場合やもっと簡単に使えるAPIを提供します。接続がどのように処理されるかを調べるには、ソースを調べてください(大きすぎない)。
例:コンテンツタイプapplication/json
といくつかのクエリパラメータでGET
リクエストを作成します。
// 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);
新しいHTTPクライアントはJava 9に同梱されていますが、
jdk.incubator.httpclient
という名前のIncubatorモジュールの一部としてです。インキュベーターモジュールは、最終的なものではないAPIを開発者の手に渡せるようにする一方で、将来のリリースでは、APIは最終化または削除のいずれかに向けて進歩します。
Java 9では、GET
リクエストを次のように送信できます。
// GET
HttpResponse response = HttpRequest
.create(new URI("http://www.stackoverflow.com"))
.headers("Foo", "foovalue", "Bar", "barvalue")
.GET()
.response();
その後、返されたHttpResponse
を調べることができます。
int statusCode = response.statusCode();
String responseBody = response.body(HttpResponse.asString());
この新しいHTTPクライアントは Java.httpclient
jdk.incubator.httpclient
モジュール、あなたはあなたのmodule-info.Java
ファイルでこの依存関係を宣言するべきです:
module com.foo.bar {
requires jdk.incubator.httpclient;
}
私もこの反応にとても感銘を受けました。
私はいくつかのHTTPを実行する必要があるプロジェクトを頻繁に行っていますが、多くのサードパーティの依存関係(他のものなどを含むものなど)を取り入れたくない場合があります。
私はこの会話のいくつかに基づいて私自身のユーティリティを書き始めました(行われた場所ではありません)
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 {
それから束または静的メソッドだけがあります。
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;
}
}
それから投稿...
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;
}
さてあなたはアイデアを得る....
これがテストです。
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);
}
あなたはここで残りを見つけることができます:
https://github.com/RichardHightower/boon
私の目標は、もう少し簡単な方法でやりたい共通のことを提供することです。
最初はHttpClient
を支持するこの article に誤解していました。
後で私はHttpURLConnection
がこの記事にとどまらないことに気づいた 記事
Googleのブログによると :
Apache HTTPクライアントはEclairとFroyoのバグが少ないです。これらのリリースに最適です。ジンジャーブレッドの場合、HttpURLConnectionが最良の選択です。そのシンプルなAPIと小さいサイズは、それをAndroidに最適にします。
透過的な圧縮と応答キャッシングはネットワークの使用を減らし、スピードを向上させ、バッテリーを節約します。新しいアプリケーションはHttpURLConnectionを使うべきです。それは私たちが将来的に私たちのエネルギーを費やすところです。
この記事 およびその他のフローに関する質問のスタックを読んだ後、私はHttpURLConnection
がもっと長い期間続くことを確信しています。
HttpURLConnections
を支持するSE質問のいくつか:
Androidでは、UrlEncodedFormEntityを使用せずにURLエンコードフォームデータでPOSTリクエストを作成します
JdkRequest
from jcabi-http (私は開発者です)を使用することもできます。これは、HttpURLConnectionの装飾、HTTP要求の起動、および応答の解析など、これらすべてを自動的に行います。
String html = new JdkRequest("http://www.google.com").fetch().body();
より多くの情報のためにこのブログ記事をチェックしてください: http://www.yegor256.com/2014/04/11/jcabi-http-intro.html
OkHttp もあります。これは、デフォルトで効率的なHTTPクライアントです。
- HTTP/2サポートにより、同じホストへのすべての要求がソケットを共有することができます。
- 接続プーリングはリクエストの待ち時間を短縮します(HTTP/2が利用できない場合)。
- 透過GZIPはダウンロードサイズを縮小します。
- 応答キャッシングは、繰り返し要求に対してネットワークを完全に回避します。
まずOkHttpClient
のインスタンスを作成します。
OkHttpClient client = new OkHttpClient();
それから、GET
リクエストを準備します。
Request request = new Request.Builder()
.url(url)
.build();
最後に、OkHttpClient
を使用して準備済みのRequest
を送信します。
Response response = client.newCall(request).execute();
詳細については、 OkHttpのドキュメント を参照してください。
httpを使用している場合は、この行を削除してください。
urlConnection.setDoOutput(true);