JavaはJava Silverの資格を取得して以来、ほとんど触っていなかったのにJavaで色々やる必要がでてきた。 その際にJavaでHTTP(S)接続をする必要がありそうなので、ざっくりどう書けばいいか調べるのと挙動を確かめておく。 またその内容を以下に備忘として残しておくことにする。
HTTPS接続する(ステータスコード200)
コード
package work; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URI; import java.net.URL; import javax.net.ssl.HttpsURLConnection; public class WorkTest { public static void main(String[] args) { try { // Java20でURLのコンストラクタによるURLオブジェクトの生成が非推奨になったようなのでこのやり方で生成 // よくみるやつはこっち(URL url = new URL("https://jsonplaceholder.typicode.com/todos/1");) URI uri = new URI("https://jsonplaceholder.typicode.com/todos/1"); URL url = uri.toURL(); // URLに紐づいたURLConnectionインスタンスを生成 HttpsURLConnection conn = (HttpsURLConnection)url.openConnection(); // メソッドを設定 conn.setRequestMethod("GET"); // 接続を確立する conn.connect(); // HTTP(S)接続の応答メッセージのステータスコードを返す int statusCode = conn.getResponseCode(); System.out.println("HTTP Status Code: "+ statusCode); // 入力ストリームを取得 InputStream input = conn.getInputStream(); // バイトストリームを文字列ストリームにし、読み込みバッファを使用し効率よく読み込めるようにする BufferedReader reader = new BufferedReader(new InputStreamReader(input)); StringBuilder output= new StringBuilder(); String line; // レスポンスを1行ずつ読み取る while((line = reader.readLine()) != null){ output.append(line); } System.out.println(output.toString()); } catch (Exception e) { e.printStackTrace(); } } }
コンソール出力
HTTP Status Code: 200 { "userId": 1, "id": 1, "title": "delectus aut autem", "completed": false}
HTTPS接続する(ステータスコード404)
接続して、ステータスコードが404等、リクエストボディがない場合の挙動を調べる。
そのために上記のコードのURLの部分を以下のように書き換えて試す。
コード
URI uri = new URI("https://www.amazon.com/404");
コンソール出力
HTTP Status Code: 404 java.io.FileNotFoundException: https://www.amazon.com/404 at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62) at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486) at java.base/sun.net.www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:2055) at java.base/sun.net.www.protocol.http.HttpURLConnection$10.run(HttpURLConnection.java:2050) at java.base/java.security.AccessController.doPrivileged(AccessController.java:571) at java.base/sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:2049) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1619) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1599) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:223) at work.WorkTest.main(WorkTest.java:35) Caused by: java.io.FileNotFoundException: https://www.amazon.com/404 at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1994) at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1599) at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:531) at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:307) at work.WorkTest.main(WorkTest.java:31)
「HTTP Status Code: 404」がコンソール出力されていることからも、分かるように「InputStream input = conn.getInputStream();」が実行された時点で例外がスローされる。 そのため、ステータスコードを読んだ後は、ステータスコードによってレスポンスを読み取るかどうか等の処理を考える必要がある。 404の場合でもレスポンスを返してくることが想定される場合は、getInputStreamではなく、getErrorStreamを使用して読み取るようにする等の工夫が必要になる。