Javaで単純なHTTPリクエストをする

Javaで簡単なHTTPリクエストを行う

1. 概要

このクイックチュートリアルでは、組み込みのJavaクラスHttpUrlConnection.を使用して、way of performing HTTP requests in Javaを紹介します。

参考文献:

JavaでのHTTP Cookieのガイド

JavaでのHTTP Cookieの迅速で実用的なガイド

Java 9および11での新しいHTTPクライアントの探索

多くの柔軟性と強力な機能を提供する新しいJava9のHttpClientAPIをご覧ください。

Java用のWebサーバーとアプリケーションサーバー

Javaで利用可能なWebおよびアプリケーションサーバーのクイックリスト。

2. HttpUrlConnection

HttpUrlConnectionクラスを使用すると、perform basic HTTP requests without the use of any additional librariesを実行できます。 必要なすべてのクラスは、java.netパッケージに含まれています。

この方法を使用することの欠点は、the code can be more cumbersome than other HTTP libraries, and it does not provide more advanced functionalities such as dedicated methods for adding headers or authenticationであるということです。

3. リクエストの作成

A HttpUrlConnection instance is created by using the openConnection() method of the URL class.このメソッドは接続オブジェクトを作成するだけで、まだ接続を確立していないことに注意してください。

HttpUrlConnectionクラスは、requestMethod属性をGET、POST、HEAD、OPTIONS、PUT、DELETE、TRACEのいずれかの値に設定することにより、すべてのタイプの要求に使用されます。

GETメソッドを使用して特定のURLへの接続を作成しましょう。

URL url = new URL("http://example.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");

4. リクエストパラメータの追加

リクエストにパラメータを追加する場合は、doOutputプロパティをtrueに設定してから、param1=value¶m2=valueの形式のStringOutputStreamに書き込む必要があります。 HttpUrlConnectionインスタンスのs:

Map parameters = new HashMap<>();
parameters.put("param1", "val");

con.setDoOutput(true);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(ParameterStringBuilder.getParamsString(parameters));
out.flush();
out.close();

parameter Mapの変換を容易にするために、MapStringに変換する静的メソッドgetParamsString()を含むParameterStringBuilderというユーティリティクラスを作成しました。必要な形式:

public class ParameterStringBuilder {
    public static String getParamsString(Map params)
      throws UnsupportedEncodingException{
        StringBuilder result = new StringBuilder();

        for (Map.Entry entry : params.entrySet()) {
          result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
          result.append("=");
          result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
          result.append("&");
        }

        String resultString = result.toString();
        return resultString.length() > 0
          ? resultString.substring(0, resultString.length() - 1)
          : resultString;
    }
}

5. リクエストヘッダーの設定

リクエストへのヘッダーの追加は、setRequestProperty()メソッドを使用して実現できます。

con.setRequestProperty("Content-Type", "application/json");

接続からヘッダーの値を読み取るには、getHeaderField()メソッドを使用できます。

String contentType = con.getHeaderField("Content-Type");

6. タイムアウトの構成

HttpUrlConnectionクラスはsetting the connect and read timeoutsを許可します。 これらの値は、サーバーへの接続が確立されるか、データが読み取り可能になるまで待機する時間間隔を定義します。

タイムアウト値を設定するには、setConnectTimeout()およびsetReadTimeout()メソッドを使用できます。

con.setConnectTimeout(5000);
con.setReadTimeout(5000);

上記の例では、両方のタイムアウト値を5秒に設定しています。

7. クッキーの取り扱い

java.netパッケージには、CookieManagerHttpCookieなどのCookieの操作を容易にするクラスが含まれています。

まず、read the cookies from a responseに対して、Set-Cookieヘッダーの値を取得し、それをHttpCookieオブジェクトのリストに解析できます。

String cookiesHeader = con.getHeaderField("Set-Cookie");
List cookies = HttpCookie.parse(cookiesHeader);

次に、add the cookies to the cookie storeを実行します。

cookies.forEach(cookie -> cookieManager.getCookieStore().add(null, cookie));

usernameというCookieが存在するかどうかを確認し、存在しない場合は、値「john」を使用してCookieストアに追加します。

Optional usernameCookie = cookies.stream()
  .findAny().filter(cookie -> cookie.getName().equals("username"));
if (usernameCookie == null) {
    cookieManager.getCookieStore().add(null, new HttpCookie("username", "john"));
}

最後に、接続を閉じて再度開いた後、add the cookies to the requestCookieヘッダーを設定する必要があります。

con.disconnect();
con = (HttpURLConnection) url.openConnection();

con.setRequestProperty("Cookie",
  StringUtils.join(cookieManager.getCookieStore().getCookies(), ";"));

8. リダイレクトの処理

trueまたはfalseパラメータを指定したsetInstanceFollowRedirects()メソッドを使用すると、enable or disable automatically following redirects for a specific connectionを実行できます。

con.setInstanceFollowRedirects(false);

enable or disable automatic redirect for all connectionsすることも可能です:

HttpUrlConnection.setFollowRedirects(false);

デフォルトでは、動作は有効になっています。

リクエストがリダイレクトを示すステータスコード301または302を返すと、Locationヘッダーを取得して、新しいURLへの新しいリクエストを作成できます。

if (status == HttpURLConnection.HTTP_MOVED_TEMP
  || status == HttpURLConnection.HTTP_MOVED_PERM) {
    String location = con.getHeaderField("Location");
    URL newUrl = new URL(location);
    con = (HttpURLConnection) newUrl.openConnection();
}

9. 応答を読む

リクエストの応答の読み取りは、parsing the InputStream of the HttpUrlConnection instanceで実行できます。

リクエストを実行するには、getResponseCode(), connect(), getInputStream()またはgetOutputStream()メソッドを使用できます。

int status = con.getResponseCode();

最後に、リクエストの応答を読み取り、content文字列に配置しましょう。

BufferedReader in = new BufferedReader(
  new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer content = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
    content.append(inputLine);
}
in.close();

close the connectionには、disconnect()メソッドを使用できます。

con.disconnect();

10. 失敗したリクエストに対する応答の読み取り

リクエストが失敗した場合、HttpUrlConnectionインスタンスのInputStreamを読み取ろうとしても機能しません。 代わりに、we can consume the stream provided by HttpUrlConnection.getErrorStream().

HTTPステータスコードを比較することで、使用するInputStreamを決定できます。

int status = con.getResponseCode();

Reader streamReader = null;

if (status > 299) {
    streamReader = new InputStreamReader(con.getErrorStream());
} else {
    streamReader = new InputStreamReader(con.getInputStream());
}

最後に、前のセクションと同じ方法でstreamReaderを読み取ることができます。

11. フルレスポンスの構築

HttpUrlConnection instanceを使用して完全な応答表現を取得することはできません。

ただし、we can build it using some of the methods that the HttpUrlConnection instance offers

public class FullResponseBuilder {
    public static String getFullResponse(HttpURLConnection con) throws IOException {
        StringBuilder fullResponseBuilder = new StringBuilder();

        // read status and message

        // read headers

        // read response content

        return fullResponseBuilder.toString();
    }
}

ここでは、ステータスコード、ステータスメッセージ、ヘッダーなど、応答の一部を読み取り、これらをStringBuilderインスタンスに追加しています。

まず、応答ステータス情報を追加しましょう。

fullResponseBuilder.append(con.getResponseCode())
  .append(" ")
  .append(con.getResponseMessage())
  .append("\n");

Next, we’ll get the headers using getHeaderFields()そしてそれらのそれぞれをHeaderName:HeaderValues:の形式でStringBuilderに追加します

con.getHeaderFields().entrySet().stream()
  .filter(entry -> entry.getKey() != null)
  .forEach(entry -> {
      fullResponseBuilder.append(entry.getKey()).append(": ");
      List headerValues = entry.getValue();
      Iterator it = headerValues.iterator();
      if (it.hasNext()) {
          fullResponseBuilder.append(it.next());
          while (it.hasNext()) {
              fullResponseBuilder.append(", ").append(it.next());
          }
      }
      fullResponseBuilder.append("\n");
});

以前と同じようにFinally, we’ll read the response contentを追加します。

getFullResponse メソッドは、リクエストのコンテンツを取得するためにcon.getInputStream()またはcon.getErrorStream()を使用する必要があるかどうかを判断するために、リクエストが成功したかどうかを検証することに注意してください。

12. 結論

この記事では、HttpUrlConnectionクラスを使用してHTTPリクエストを実行する方法を示しました。 例の完全なソースコードはover on GitHubにあります。