【Java】HttpClientでAPIを叩いてみる①

# HttpClient

この記事がよくまとまっていてわかりやすかった。

> Java 8以前のバージョンでは、`HttpURLConnection`クラスを利用する方法が一般的だった。しかし、このクラスはJava SE 1.1の頃（1996年）に追加された**非常に古い**もので、機能面でも使い勝手の面でも、現在のアプリケーション開発で使うには多くの問題を抱えている。

> HTTPクライアントAPIの特徴としては、次の点が挙げられる。
> * **HTTP/2**をサポート
> * WebSocketをサポート
> * リクエスト/レスポンスをリアクティブストリームとして処理
...etc

https://news.mynavi.jp/techplus/article/imajava-10/

ちらほら出てくる`HTTP/2`について。
![スクリーンショット 2023-03-01 14.21.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/777324/8179e39e-e752-58ad-37f3-490252341e6e.png)
> 画像引用
https://www.kagoya.jp/howto/it-glossary/security/http-2/

リファレンス。

https://docs.oracle.com/javase/jp/11/docs/api/java.net.http/java/net/http/HttpClient.html


# 環境

| System | Version |
| :-: | :-: |
| OS | MacOS Monterey(12.1) |
| Intelli J | 2022/2/2 |
| sdk | Temurin 11.0.14 |

# APIを叩く

内閣官房が出しているコロナに関するAPIを叩いてみる。

https://corona.go.jp/dashboard/

絞り込みは`昨日までの東京都`の累計コロナ感染者数を見る。
（2023年3月1日 現在）

https://opendata.corona.go.jp/api/Covid19JapanAll


```java:Corona.java
package API;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Corona {
    public static void main(String[] args) {
        String url = "https://opendata.corona.go.jp/api/Covid19JapanAll?dataName=東京都&date=20230228";
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest req = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .GET()
                .build();
        try {
            HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());
            System.out.println(res);
            System.out.println(res.body());
        } catch (IOException | InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}
```

`send()`メソッドにより、
`IOException`と`InterruptedException`の例外処理が必須。

`.GET()`はなくてもデフォルトでGETメソッドになるみたい。

> `public static HttpClient newHttpClient()`
デフォルト設定には: **"GET"リクエスト・メソッド**、HTTP/2のプリファレンス、NEVERのリダイレクション・ポリシー、「デフォルト・プロキシ・セレクタ」、および「デフォルトのSSLコンテキスト」があります。

https://docs.oracle.com/javase/jp/11/docs/api/java.net.http/java/net/http/HttpClient.html

```java:実行結果
(GET https://opendata.corona.go.jp/api/Covid19JapanAll?dataName=東京都&date=20230228) 200
{"errorInfo":{"errorFlag":"0","errorCode":null,"errorMessage":null},
"itemList":[
    {"date":"2023-02-28",
    "name_jp":"東京都",
    "npatients":"4316448"}
]}
```
`HttpResponse.BodyHandlers.ofString()`としたため
`res.body()`は`String型`で返ってくる。
そのまま`json`にキャストしたりはできない。

> | 修飾子と型 | メソッド | 説明 |
> | :-: | :-: | :-: |
> | T | body() | 本文を返します。 |


https://docs.oracle.com/javase/jp/11/docs/api/java.net.http/java/net/http/HttpResponse.html

# jsonを使った取り出し方

`json`形式で読み込むために外部ライブラリを使う。

https://mvnrepository.com/artifact/org.json/json/20230227

追加する。

https://qiita.com/hideo9080/items/80abd75fa6f3cdeff6ea

```java:Corona.java
import org.json.JSONArray;
import org.json.JSONObject;

JSONObject jsonObject = new JSONObject(res.body());
JSONArray itemList = jsonObject.getJSONArray("itemList");
JSONObject data = itemList.getJSONObject(0);
int nPatients = data.getInt("npatients");
System.out.println(nPatients);
```

欲しい値が**json**,**配列**,**int**なのかを見極めながら取り出す。

```java:実行結果
4316448
```
こんなにいたのか。

# 次の記事

レスポンスが写真とか`GIF`の場合に、自動で表示したり保存したりするところまで書きました。

https://qiita.com/syoshika_/items/e90a6acd9335a2380db8