java.net.URLConnection`]1の使用については、ここでかなり頻繁に質問されており、Oracle tutorial はそれについてtoo簡潔に述べています。
そのチュートリアルでは、基本的にGETリクエストを発行し、レスポンスを読む方法しか示していません。POSTリクエストの実行、リクエストヘッダの設定、レスポンスヘッダの読み込み、クッキーの処理、HTMLフォームの送信、ファイルのアップロードなどの使用方法については、どこにも説明されていないのです。
では、java.net.URLConnection
を使用して、"advanced"HTTPリクエストを発生させて処理するにはどうすればよいのでしょうか?
や
ArrayIndexOutOfBoundsExceptionなどの
IOExceptionや
RuntimeException` を自分で処理する必要がありますまず、最低でも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
形式で、&
で連結する必要があります。また、通常は URLEncoder#encode()
を用いて、指定された文字セットでクエリパラメータを URL-encode することになるでしょう。
String#format()
は、単に便宜上のものです。文字列の連結演算子 +
が2回以上必要な場合は、この方法を使うことをお勧めします。些細なことです。これはデフォルトのリクエストメソッドです。
URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...
任意のクエリ文字列は ?
を使って URL に連結する必要があります。Accept-Charset][4]ヘッダは、パラメータがどのようなエンコーディングであるかをサーバーに伝えるヒントになります。もしクエリー文字列を送信しないのであれば、
Accept-Charsetヘッダは無視してもかまいません。もし、ヘッダを設定する必要がなければ、[
URL#openStream()`]5のショートカットメソッドを使用することもできます。
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()][10] を
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 フォームをプログラムで送信したい場合は、<input type="hidden">
要素の name=value
ペアをクエリー文字列に取り込むことを忘れないようにしてください。input type="submit">要素の
name=valueのペアをクエリ文字列に追加します。これは、プログラム的に "press" したいものです(これは通常サーバー側で、ボタンが押されたか、もしそうならどれかを区別するために使用されているからです)。 また、取得した [
URLConnection][11] を [
HttpURLConnection][12] にキャストし、その [
HttpURLConnection#setRequestMethod()][13] を代わりに使用することができます。しかし、この接続を出力に使用する場合は、[
URLConnection#setDoOutput()][14]を
true` に設定する必要があります。
HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
httpConnection.setRequestMethod("POST");
// ...
HttpServlet
であれば、その doPost()
メソッドが呼ばれ、 HttpServletRequest#getParameter()
でパラメータが利用できるようになります。URLConnection#connect()
で明示的に起動できますが、 URLConnection#getInputStream()
などでレスポンスボディなど、HTTP レスポンスの情報を取得したい場合は、必要に応じて自動的にリクエストが起動されます。上記の例では、まさにそれを行っているので、connect()
の呼び出しは実際には余計なものです。HttpURLConnection
が必要です。必要であれば、最初にキャストしてください。
int status = httpConnection.getResponseCode();
2.HTTPレスポンスヘッダ。
for (Entry<String, Listに
charset` パラメータが含まれる場合、レスポンスボディはテキストベースである可能性が高いので、サーバサイドで指定された文字エンコーディングで処理したいと思います。
String contentType = connection.getHeaderField("Content-Type");
文字列 charset = null;
for (String param : contentType.replace(" ", "").split(";") { (String param : contentType.replace(" ", ""))
if (param.startsWith("charset=")){。
charset = param.split("=", 2)1;
ブレーク
}
}
if (charset != null) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(response, charset))){
for (String line; (line = reader.readLine()) != null;){
// ...System.out.println(line) ?
}
}
} else {
// バイナリコンテンツである可能性が高いので、InputStream/OutputStreamを使用する。
}サーバー側のセッションは、通常、クッキーによってバックアップされています。いくつかのウェブフォームは、あなたがログインしていること、および/または、セッションによって追跡されることを要求します。クッキーを管理するために、CookieHandler
APIを使用することができます。すべての HTTP リクエストを送信する前に、CookiePolicy
を ACCEPT_ALL
に設定した CookieManager
を準備する必要があります。
// 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();
// ...
なお、この方法は、すべての状況下で常に正しく動作するわけではないことが知られています。もしこれが失敗したら、クッキーヘッダを手動で収集し設定するのが一番です。基本的には、ログインまたは最初の 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]);
}
// ...
は、
expiresや
pathなど、サーバーサイドには無関係な Cookie の属性を取り除くためにあります。あるいは、
split()の代わりに
cookie.substring(0, cookie.indexOf(';'))` を使用することもできます。HttpURLConnection][28] はデフォルトで、
connection.setRequestProperty("Content-Length", contentLength);を使ってコンテンツの長さを固定にしたかどうかに関わらず、実際に送る前に *全体* のリクエストボディをバッファーします。これは、大きな POST リクエスト (例えば、ファイルのアップロード) を同時に送信するときに、
OutOfMemoryExceptionを引き起こすかもしれません。これを避けるには、[
HttpURLConnection#setFixedLengthStreamingMode()`]29を設定する必要があります。
httpConnection.setFixedLengthStreamingMode(contentLength);
しかし、コンテンツの長さが本当に事前にわからない場合は、適宜 HttpURLConnection#setChunkedStreamingMode()
を設定することで、チャンクドストリーミングモードを使用することができます。これにより、HTTP Transfer-Encoding
ヘッダが chunked
に設定され、リクエストボディがチャンク単位で送信されるようになります。以下の例では、1KBのチャンクでボディが送信されます。
httpConnection.setChunkedStreamingMode(1024);
実際のWebブラウザでは問題なく動作しているのに、リクエストすると予期せぬレスポンスが返ってくる](https://stackoverflow.com/questions/13670692/403-forbidden-with-java-but-not-web-browser)ということが起こり得ます。サーバー側はおそらく、[`User-Agent`][32] リクエストヘッダに基づいてリクエストをブロックしているのでしょう。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.
HTTP レスポンスコードが 4nn
(Client Error) または 5nn
(Server Error) の場合、 HttpURLConnection#getErrorStream()
を読み込んで、サーバーから何か有用なエラー情報が送信されていないか確認するとよいでしょう。
InputStream error = ((HttpURLConnection) connection).getErrorStream();
HTTPレスポンスコードが-1であれば、接続とレスポンスの処理に何か問題があったということです。古い JRE では、HttpURLConnection
の実装が、接続を維持する際にややバグがあります。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()
によって部品を利用できるようになります(注意:このように getParameter()
などのように not です!)。しかし、getPart()
メソッドは比較的新しく、Servlet 3.0 (Glassfish 3, Tomcat 7, etc) で導入されました。Servlet 3.0以前では、Apache Commons FileUpload を使って multipart/form-data
リクエストをパースするのがベストな選択でしょう。また、FileUploadとServelt 3.0の両方のアプローチの例については、この回答を参照してください。ウェブスクレイパーを書くために、HTTPS URLに接続する必要がある場合があります。そのような場合、javax.net.ssl.SSLException.Allow' というエラーに直面するかもしれません。SSL証明書を最新に保っていないHTTPSサイトでは、
Not trusted server certificateや
java.security.cert.CertificateException:java.security.certificateException: No subject alternative DNS name matching [hostname] foundor
javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_nameon some misconfigured HTTPS sites.このようなサイトでは、SSL証明書を最新にしていない可能性があります。 ウェブスクレイパーのクラスで次のような
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 便利です :)
HTTP を扱う場合、基本クラスである URLConnection
よりも HttpURLConnection
を参照した方が便利な場合がほとんどです (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。]https://github.com/kevinsawicki/http-request。) 基本的に「HttpUrlConnection」の上にあるラッパーで、今すぐリクエストを行いたい場合やソースを確認できる場合に備えて、はるかにシンプルなAPIを提供します。 (it'。;大きすぎません。) 接続の処理方法を確認します。
例:コンテンツタイプ「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を行う必要があるプロジェクトに参加しており、サードパーティの依存関係(他の依存関係などをもたらすなど)を多く持ち込みたくない場合があります。)。
私はこの会話の一部に基づいて自分のユーティリティを書き始めました(どこで行われたかではありません):
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。
私の目標は、もう少し簡単な方法でやりたい一般的なことを提供することです。...
新しいHTTPクライアントはJava 9に同梱されていますが、その一部として出荷されています。
jdk.incubator.httpclient
という名前のインキュベーターモジュール。 インキュベーターモジュールです。 非最終的な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クライアントは< del> java.httpclient
にあるため jdk.incubator.httpclient
モジュール、この依存関係を module-info.java
ファイルで宣言する必要があります。
module com.foo.bar {
requires jdk.incubator.httpclient;
}
最初は、「HttpClient」を支持するこの記事に惑わされました。
後で、「HttpURLConnection」がこの記事から残ることになることに気づきました。
Googleブログに従って:
Apache HTTPクライアントのバグは、EclairとFroyoで少なくなっています。 これらのリリースには最良の選択です。 Gingerbreadの場合、HttpURLConnectionが最適です。 シンプルなAPIと小型サイズにより、Androidに最適です。
透明な圧縮と応答のキャッシュにより、ネットワークの使用が削減され、速度が向上し、バッテリーが節約されます。 新しいアプリケーションでは、HttpURLConnectionを使用する必要があります。これは、今後エネルギーを費やす場所です。
この記事やその他のスタックオーバーフローの質問を読んだ後、「HttpURLConnection」はより長い期間続くと確信しています。
HttpURLConnections
を支持するSE質問の一部:
https://stackoverflow.com/questions/4330392/on-android-make-a-post-request-with-url-encoded-form-data-without-using-urlenco / 4794289#4794289。
https://stackoverflow.com/questions/4221420/httpsost-works-in-java-project-not-in-android。
OkHttpもあります。これは、デフォルトで効率的なHTTPクライアントです。
-HTTP / 2サポートにより、同じホストへのすべてのリクエストでソケットを共有できます。 -接続プールにより、リクエストのレイテンシが減少します(HTTP / 2が利用できない場合)。 -透明なGZIPはダウンロードサイズを縮小します。 -レスポンスキャッシュにより、繰り返しリクエストのためにネットワークが完全に回避されます。
まず、 OkHttpClient
のインスタンスを作成します。
OkHttpClient client = new OkHttpClient();
次に、「GET」リクエストを準備します。
Request request = new Request.Builder()
.url(url)
.build();
最後に、 OkHttpClient
を使用して、準備された リクエスト
を送信します。
Response response = client.newCall(request).execute();
詳細については、OkHttpのドキュメントを参照してください。
jcabi-httpの[jdkRequest`](http:// http .jcabi.com)(私は開発者です)、これはすべてこの作業を行い、HTPURConnectionを装飾します。
String html = new JdkRequest("http://www.google.com").fetch().body();
詳細については、このブログ投稿を確認してください。http://www.yegor256.com/2014/04/11/jcabi-http-intro.html。
http getを使用している場合は、この行を削除してください。
urlConnection.setDoOutput(true);