JSP/Servlet から WebAPI（フリー、APIキー不要）つかってみる

Java の JSP、Servlet から WebAPI を使ってみる
使う WebAPI はこれ、どれもランダムに画像はいった情報を返してくれる（公開してくれてる方には感謝しかない！！）

- ユーザー情報取得API
https://randomuser.me/api
- ねこ画像取得API
https://aws.random.cat/meow
- きつね画像取得API
https://randomfox.ca/floof
- 星座情報取得API
https://livlog.xyz/hoshimiru/constellation

ここでは WebAPI つかうために3つをやってみる
説明で使ってるサンプルプロジェクトのおおもとは GitHub [java-webapp-clump](https://github.com/sueasen/java-webapp-clump) にあります

- JSP から WebAPI 実行 ※JSPって書いてるけど HTML, JavaScript でも使えるところ
- Servlet から JSON 返却（Java で WebAPI 作る）
- Servlet から WebAPI 実行して JSON 返却

# JSP から WebAPI 実行

まずは JSP から WebAPI を実行して JSON を処理してみる
JSP と書いてるけど JSP(HTML) で JSON からとった情報を表示する枠だけ作っておいて JavaScript で WebAPI 実行 → `response` から JSON 取得 → 画面に情報表示の流れ

### JSP 作る（WebAPIから取得する JSON 情報を表示する枠を作る）

- `/java-webapp-clump/src/main/webapp/WEB-INF/view` 直下に `apiWork.jsp` 作成

```jsp:apiWork.jsp
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ page isELIgnored="false" %>

<!doctype html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>JavaDevelop</title>
    <link rel="shortcut icon" href="<c:url value="/assets/favicon.ico" />">
    <link rel="stylesheet" href="<c:url value="/assets/bootstrap.min.css" />">
    <link rel="stylesheet" href="<c:url value="/assets/bootstrap-icons.css" />">
    <link rel="stylesheet" href="<c:url value="/assets/styles.css" />">
</head>

<body>

    <%@ include file="./_headerNavbar.jsp" %>

    <main>
        <div class="container workspace">
            <h2>WebAPI やってみる</h2>
            <hr/>

            <h4>1. JSP から WebAPI 実行 </h4>
            <button id="apicat" class="btn btn-info">ねこ情報取得</button>
            <p>WebAPI から取得した 情報（JSON）</p>
            <textarea id="apicat_json" rows="2" cols="80" disabled placeholder="結果は．．．"></textarea>
            <p>WebAPI から取得した画像</p>
            <img id="apicat_img" src="">
            <hr/>
            <button id="apiuser" class="btn btn-info">ユーザ情報取得</button>
            <p>WebAPI から取得した 情報（JSON）</p>
            <textarea id="apiuser_json" rows="3" cols="80" disabled placeholder="結果は．．．"></textarea>
            <p>WebAPI から取得した画像</p>
            <img id="apiuser_img" src="">
            <hr/>

        </div>
    </main>

    <footer class="footer mt-auto fixed-bottom py-3 bg-secondary"></footer>

    <script src="<c:url value="/assets/bootstrap.bundle.min.js" />"></script>
    <script src="<c:url value="/assets/script.js" />"></script>
</body>

</html>
```

### Servlet 作る

- `/java-webapp-clump/src/main/java/presentation/servlet` 直下にクラス `ApiWorkServlet.java` を作成
- `@WebServlet` に設定する URL を `/api_work` にする
- JSP のパスを `/WEB-INF/view/apiWork.jsp` にする

```Java:ApiWorkServlet.java
package presentation.servlet;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * {@link ApiWorkServlet}
 */
@WebServlet("/api_work")
public class ApiWorkServlet extends HttpServlet {

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String view = "/WEB-INF/view/apiWork.jsp";
		RequestDispatcher dispatcher = request.getRequestDispatcher(view);
		dispatcher.forward(request, response);
	}

}
```

### JavaScript を追加（WebAPI実行してJSON情報表示）

- `/java-webapp-clump/src/main/webapp/assets` の `script.js` に追加
- `fetch` で WebAPI を実行して実行結果から json 取得して処理
一つ目の `then` で `response` から `JSON` 取得
二つ目の `then` で `JSON` 使った処理がかける 
JavaScript のところの概要は [【JavaScript きほんとか雑多なめも Web API (Fetch API)】](https://qiita.com/sueasen/items/5b6db9bddcf655ecd055#web-api-fetch-api) を参照

```javascript:script.js
/**
 * html 読込時の処理
 */
window.addEventListener('load', (e) => {

	// ねこ情報取得
    document.querySelector("#apicat").addEventListener("click", () => {
        fetch("https://aws.random.cat/meow")  // 実行する url　を fetch の引数に指定 
            .then(response => response.json()) // WebAPI の実行結果 response から JSON 取得
            .then(json => {
                // json を使った処理を書くところ
                console.log(json);
                document.querySelector("#apicat_json").value = JSON.stringify(json);
                document.querySelector("#apicat_img").src = json.file;
                document.querySelector("#apicat_img").height = 300;
            })
            .catch((error) => console.log(error)); // エラー発生時の処理
    });

	// ユーザ情報取得
    document.querySelector("#apiuser").addEventListener("click", () => {
        fetch("https://randomuser.me/api")
            .then(response => response.json())
            .then(json => {
                console.log(json);
                document.querySelector("#apiuser_json").value = JSON.stringify(json);
                document.querySelector("#apiuser_img").src = json.results[0].picture.large;
                document.querySelector("#apiuser_img").height = 300;
            })
            .catch((error) => console.log(error));
    });
});

```

### JSP・Servlet・JavaScript の動作確認

- http://localhost:8080/java-wabapp-clump/api_work でブラウザ表示を確認（以下みたいのが表示されればOK）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/a1fd25dc-29e9-be21-06e8-4583286d2bbd.png)

## ちょっと練習

JSP・JavaScript に きつねと星座のWebAPIを追加してみよう

- JSP `apiWork.jsp`
ねこ、ユーザ情報のところを参考にきつね、星座の枠を追加
ボタン・テキスト・イメージタグの `id` を変更する
この `id` を JavaScript で指定することで JSP(HTML) で用意したタグを取得して処理してくことになります    
- JavaScript `script.js`
ねこ、ユーザ情報のところを参考にきつね、星座の処理を追加
`document.querySelector` で指定してる `id` を JSP(HTML) に合わせる
`fetch` の引数で指定してる `URL` を以下に変更する
 ・きつね：https://randomfox.ca/floof
 ・星座：https://livlog.xyz/hoshimiru/constellation?lat=35.605&lng=140.123&date=2023-1-18&hour=11&min=0
`json` から取得してるイメージタグの `src` に設定してる画像の値を変更する


# Servlet から JSON 返却（Java で WebAPI 作る）

Java で WebAPI として JSON 返却するものを作ってみる
Java の `Servlet` から JSON 返却するようにして JSP(HTML) で用意した枠に JavaScript で WebAPI 実行 して画面に表示してみる

### pom 修正（JSONライブラリ追加）

- `/java-webapp-clump/pom.xml` を修正
- `<dependencies>` ・・・ `</dependencies>` の間に JSON ライブラリ `jackson` の `dependency` を追加

```XML:pom.xml
    <!-- JSON jackson -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.14.1</version>
    </dependency>
```

### Servlet 作る（JSON返却する Web API）

- `/java-webapp-clump/src/main/java/presentation/servlet` 直下にクラス `ApiWorkJson1Servlet.java` を作成
- `@WebServlet` に設定する URL を `/api_work_json1` にする
- JSON で返す情報をつくる（2パターン）
    - `Map` 利用 : キー、値がそのまま JSON になる
    - `Dto` 利用 : クラス変数名がキー、クラス変数の値が JSON のキー、値になる 
- `response` に JSON 返却するように設定
    - `response.setCharacterEncoding("UTF-8");` で文字コード設定
    - `response.setContentType("application/json");` でコンテンツタイプ設定
    - `response.getWriter().print(new ObjectMapper().writeValueAsString(xxx));` で `Map` や `Dto` で作った情報よりJSON変換して設定

```Java:ApiWorkJson1Servlet.java
package presentation.servlet;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.ObjectMapper;

import dto.Memo;

/**
 * {@link ApiWorkJson1Servlet}
 */
@WebServlet("/api_work_json1")
public class ApiWorkJson1Servlet extends HttpServlet {

  /**
   * {@inheritDoc}
   */
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    // Map で作る Json 変換するデータ
    Map<String, Object> apiData = new HashMap<>();
    apiData.put("name", "Servlet JSON 返却(Map)");
    apiData.put("message", "Servlet で JSON 返す Web API を作る（Map利用）");
    // Dto で作る Json 変換するデータ
    // Memo apiData = new Memo( // クラスMemo は name, message のクラス変数、getter, setter を持つ 
    //    "Servlet JSON 返却(Dto)", "Servlet で JSON 返す Web API を作る（Dto利用）");

    response.setCharacterEncoding("UTF-8"); // 文字コード指定
    response.setContentType("application/json"); // コンテンツタイプ設定
    response.getWriter().print(new ObjectMapper().writeValueAsString(apiData)); // Map や Dto を JSON 変換して設定
  }

}
```


### JSP 追記（JSON 情報を表示する枠を作る）

- `/java-webapp-clump/src/main/webapp/WEB-INF/view/apiWork.jsp` に追記(mainタブのdivタブ(container workspace)の中)

```JSP:apiWork.jsp
            <h4>2. Servlet から JSON 返却（Java で WebAPI 作る） </h4>
            <button id="apijava1" class="btn btn-info">Servlet JSON 情報取得</button>
            <p>WebAPI から取得した 情報（JSON）</p>
            <textarea id="apijava1_json" rows="2" cols="80" disabled placeholder="結果は．．．"></textarea>
            <p>WebAPI から取得した name : message </p>
            <p id="apijava1_namemsg"></p>
            <hr/>
```

### JavaScript を追加（WebAPI実行してJSON情報表示）

- `/java-webapp-clump/src/main/webapp/assets` の `script.js` に追記（【JSPからWebAPI実行】で追加した `window.addEventListener('load', (e) => { ・・・ }` の中）
- `document.querySelector` で指定してる `id` を JSP に合わせる
- `fetch` の URL, 2つめの `then` のとこの 処理を作った WebAPI に合わせる

```javascript:script.js

    // Servlet JSON (Map)情報取得
    document.querySelector("#apijava1").addEventListener("click", (e) => {
        fetch("http://localhost:8080/java-wabapp-clump/api_work_json1")
            .then(response => response.json())
            .then(json => {
                console.log(json);
                document.querySelector("#apijava1_json").value = JSON.stringify(json);
                document.querySelector("#apijava1_namemsg").innerText = json.name + "：" + json.message;
            })
            .catch((error) => console.log(error));
    });

```

### JSP・Servlet・JavaScript の動作確認

- http://localhost:8080/java-wabapp-clump/api_work でブラウザ表示を確認（以下みたいのが追加されればOK）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/b57446d6-841e-8d06-10aa-d3c1b3fe026c.png)

## ちょっと練習

Servlet・JSP・JavaScript を変えて Dto 表示、Map・Dto 変えて表示をやってみよう

1. Servlet のコメントアウトを変えて Dto の Memo の情報を表示してみる
1. Servlet から Map, Dto の情報を変えながら表示してみる
    - apiWork.jsp
      Map, Dto を選択する `select` タグ を `button` タグ の前などに追加
      ```JSP:apiWork.jsp
            <select id="apijava1_type" class="select">
                <option value="map">MAP</option>
                <option value="dto">Dto</option>
            </select>
      ```
    - script.js
      1. WebAPI を実行してる `fetch` の前に `select` タグの値を取得し、変数 `type` に設定
      1. `fetch` の引数で指定してる URL に クエリ―パラメータを追加
      ```JavaScript:script.jsp
        // 変数 type に select タグの値を取得して設定
        let type = document.querySelector("#apijava1_type").value;
        // クエリ―パラメータは url に "?key1=value1&key2=value2・・" で設定 
        // 例) https://xxx.yyy.com?name=suzuki&age=49&height=180
        fetch("http://localhost:8080/java-wabapp-clump/api_work_json1?type=" + type)
      ```
    - ApiWorkJson1Servlet.java
      1. `request.getParameter("type")` でクエリ―パラメータの値を取得
      1. 上で取得した値が `map`, `dto` で処理を分岐して JSON 変換するオブジェクトを Map, Dto で切り替えて設定
      ```Java:ApiWorkJson1Servlet.java # 参考 : type とった後の分岐などは考えて追加してみよう 
        // クエリ―パラメータからキー：type の値を取得する方法
        String type = request.getParameter("type");
        // オブジェクト（Map or Dto）をJSON 変換してレスポンスに設定してるところの処理
        response.getWriter().print(new ObjectMapper().writeValueAsString(apiData));
      ```


# Servlet から WebAPI 実行して JSON 返却

Servlet で WebAPI を実行して JSON 返却する場合、Servlet の中でサービスの好きな形に JSON を変えることができるので使い勝手が良くなる
また WebAPI 実行に認証用の情報が必要な場合など認証用の情報をフロントに置かずに処理できるのでセキュリティの考慮が楽になる
ここでは実行した WebAPI の結果をいろいろなパターンで返しながらやってみる
- WebAPI の結果をそのまま JSON で返却
- WebAPI の結果を Map にして必要なものだけにしてJSON返却
- WebAPI の結果を Dto にして必要なものだけにしてJSON返却

## WebAPI の結果をそのまま JSON で返却

### Servlet 作る（そのまま JSON 返却）

- `/java-webapp-clump/src/main/java/presentation/servlet` 直下にクラス `ApiWorkJson2Servlet.java` を作成
- `@WebServlet` に設定する URL を `/api_work_json2` にする
- WebAPI を 実行して JSON を取得
    - `URL` のインスタンス作成の引数に実行する URL を設定し変数 `url` に格納
    - `(HttpURLConnection) url.openConnection()` で実行する WebAPI とのコネクションを開き `urlConnection` に格納
    - `urlConnection.setRequestMethod("GET")` で WebAPI に実行するメソッドを設定
    - `urlConnection.getInputStream()` で結果取得用のオブジェクトを生成し `stream` に格納
    - `urlConnection`, `stream` は必ず閉じる必要があるので `try-with-resources` で宣言 
    - `new ObjectMapper().readTree(stream)` で JSON を取得
- `response` に JSON 返却するように設定
    - `response.setCharacterEncoding("UTF-8");` で文字コード設定
    - `response.setContentType("application/json");` でコンテンツタイプ設定
    - `response.getWriter().print(json);` で JSON を設定

```Java:ApiWorkJson2Servlet.java
package presentation.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * {@link ApiWorkJson2Servlet}
 */
@WebServlet("/api_work_json2")
public class ApiWorkJson2Servlet extends HttpServlet {

  /**
   * {@inheritDoc}
   */
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    URL url = new URL("https://randomuser.me/api");
    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestMethod("GET");

    try (
        AutoCloseable closeable = () -> urlConnection.disconnect();
        InputStream stream = urlConnection.getInputStream();) {

      JsonNode json = new ObjectMapper().readTree(stream);
      response.setCharacterEncoding("UTF-8");
      response.setContentType("application/json");
      response.getWriter().print(json);

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
```

### JSP 追記（JSON 情報を表示する枠を作る）

- `/java-webapp-clump/src/main/webapp/WEB-INF/view/apiWork.jsp` に追記(mainタブのdivタブ(container workspace)の中)

```JSP:apiWork.jsp
            <h4>3. Servlet から WebAPI 実行して JSON 返却</h4>
            <button id="apijava2" class="btn btn-info">Servlet JSON 情報取得</button>
            <p>WebAPI から取得した 情報（JSON）</p>
            <textarea id="apijava2_json" rows="2" cols="80" disabled placeholder="結果は．．．"></textarea>
            <p>WebAPI から取得した画像</p>
            <img id="apijava2_img" src="">
            <hr/>
```

### JavaScript を追加（WebAPI実行してJSON情報表示）

- `/java-webapp-clump/src/main/webapp/assets` の `script.js` に追記（【JSPからWebAPI実行】で追加した `window.addEventListener('load', (e) => { ・・・ }` の中）
- `document.querySelector` で指定してる `id` を JSP に合わせる
- `fetch` の URL, 2つめの `then` のとこの 処理を作った WebAPI に合わせる

```javascript:script.js

    // Servlet JSON (Map)情報取得
    document.querySelector("#apijava2").addEventListener("click", (e) => {
        fetch("http://localhost:8080/java-wabapp-clump/api_work_json2")
            .then(response => response.json())
            .then(json => {
                console.log(json);
                document.querySelector("#apijava2_json").value = JSON.stringify(json);
                document.querySelector("#apijava2_img").src = json.results[0].picture.large;
                document.querySelector("#apijava2_img").height = 300;
            })
            .catch((error) => console.log(error));
    });
```

### JSP・Servlet・JavaScript の動作確認

- http://localhost:8080/java-wabapp-clump/api_work でブラウザ表示を確認（以下みたいのが追加されればOK）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51758/010dc976-7ba5-6c25-04cd-d221b5aed4d5.png)

## WebAPI の結果を Map にして必要なものだけにしてJSON返却

### Servlet 修正（Map にして必要なものだけJSON返却）

- `/java-webapp-clump/src/main/java/presentation/servlet/ApiWorkJson2Servlet.java` を修正
- `try - catch` の中を修正
    - `ObjectMapper` のインスタンスを生成して `mapper` に格納
    - `mapper.readTree(stream)` で JSON 取得
    - `map` を作って`json.get("key")`, `json.get(index)` で取りたい情報を取得し設定（今回はユーザ情報画像）
    - `mapper.writeValueAsString(map)` で JSON 返却

```Java:ApiWorkJson2Servlet.java

    URL url = new URL("https://randomuser.me/api");
    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestMethod("GET");

    try (
        AutoCloseable closeable = () -> urlConnection.disconnect();
        InputStream stream = urlConnection.getInputStream();) {

      ObjectMapper mapper = new ObjectMapper();
      JsonNode json = mapper.readTree(stream);
      Map<String, Object> map = new HashMap<>();
      map.put("large", json.get("results").get(0).get("picture").get("large"));
      response.setCharacterEncoding("UTF-8");
      response.setContentType("application/json");
      response.getWriter().print(mapper.writeValueAsString(map));

    } catch (Exception e) {
      e.printStackTrace();
    }
```

※単純に WebAPI の結果すべてを Map に入れたい場合は以下の感じでできる
```Java:参考
        Map<String, Object> map = new ObjectMapper().readValue(stream, new TypeReference<Map<String, Object>>() {});
```

### JavaScript 修正（画像設定のところを修正）

- `/java-webapp-clump/src/main/webapp/assets` の `script.js` を修正（JSON から画像を取得してる箇所）
- Servlet に合わせて `large` のみにする

```javascript:script.js
                document.querySelector("#apijava2_img").src = json.large;
```

### Servlet・JavaScript の動作確認

- http://localhost:8080/java-wabapp-clump/api_work でブラウザ表示を確認（上でやってたやつと変わらなければOK）


## WebAPI の結果を Dto にして必要なものだけにしてJSON返却

### Dto 作る（必要なものだけ持つやつ）

- `/java-webapp-clump/src/main/java/dto` 直下に `UserInfo.java` を作成
- JSON に合わせて必要なクラス変数を定義する
- クラスに `@JsonIgnoreProperties(ignoreUnknown = true)` を必ずつける（ないとJSONに合わせて変数定義する必要あり）
- クラス `Users`, `Picture` は各々で作成してもOK（ファイル分けるのめんどくさかったのでインナークラスで定義）

```Java:UserInfo.java
package dto;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

/**
 * {@link UserInfo}
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserInfo {

  List<Users> results;

  /**
   * users を設定します
   * @param users ユーザ情報リスト
   */
  public void setResults(List<Users> results) {
    this.results = results;
  }

  /**
   * users を取得します
   * @return users
   */
  public List<Users> getResults() {
    return results;
  }

  /**
   * {@link Users}
   */
  @JsonIgnoreProperties(ignoreUnknown = true)
  public static class Users {

    Picture picture;

    /**
     * picture を設定します
     * @param picture picture情報
     */
    public void setLarge(Picture picture) {
      this.picture = picture;
    }

    /**
     * picture を取得します
     * @return picture
     */
    public Picture getPicture() {
      return picture;
    }
  }

  /**
   * {@link Users}
   */
  @JsonIgnoreProperties(ignoreUnknown = true)
  public static class Picture {

    String large;

    /**
     * large を設定します
     * @param large large画像
     */
    public void setLarge(String large) {
      this.large = large;
    }

    /**
     * large を取得します
     * @return large
     */
    public String getLarge() {
      return large;
    }
  }
}

```

### Servlet 修正（Dto にして必要なものだけJSON返却）

- `/java-webapp-clump/src/main/java/presentation/servlet/ApiWorkJson2Servlet.java` を修正
- `try - catch` の中を修正
    - `mapper.readValue(stream, UserInfo.class);` で JSON を `UserInfo` で取得
    - `mapper.writeValueAsString(返したい情報)` で JSON 返却

```Java:ApiWorkJson2Servlet.java

    URL url = new URL("https://randomuser.me/api");
    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestMethod("GET");

    try (
        AutoCloseable closeable = () -> urlConnection.disconnect();
        InputStream stream = urlConnection.getInputStream();) {

      ObjectMapper mapper = new ObjectMapper();
      UserInfo userInfo = mapper.readValue(stream, UserInfo.class);

      response.setCharacterEncoding("UTF-8");
      response.setContentType("application/json");
      response.getWriter().print(
          mapper.writeValueAsString(userInfo.getResults().get(0).getPicture()));

    } catch (Exception e) {
      e.printStackTrace();
    }
```

### Dto, Servlet の動作確認

- http://localhost:8080/java-wabapp-clump/api_work でブラウザ表示を確認（上でやってたやつと変わらなければOK）

## ちょっと練習

Servlet で色んな画像取得の WebAPI を取得して表示してみよう

- JSP `apiWork.jsp`
    `select` タブを用意して実行する WebAPI のクエリ―パラメータを指定できるようにする

- JavaScript `script.js`
    上で設定した `select` タブの値を取得してクエリ―パラメータを設定して WebAPI を実行する
    WebAPI 実行結果から画像を取得してるところの `json.xxxxx` は固定にする(なんでもOK)

- Java`ApiWorkJson2Servlet.java`
    クエリ―パラメータから取得した値によって処理を分岐していろんな画像取得の WebAPI を実行する
    実行結果より画像を取得し上で固定した `json.xxxxx` に合わせて設定した JSON を返却する
    - ねこ画像取得API : https://aws.random.cat/meow
    - きつね画像取得API : https://randomfox.ca/floof
    - 星座情報取得API : https://livlog.xyz/hoshimiru/constellation?lat=35.605&lng=140.123&date=2023-1-18&hour=11&min=0


# Apendex（参考）

## Servlet から WebAPI 実行（POST, JSON設定）

WebAPI を実行するときに POST でJSONデータを送る必要があることが多いので参考

```Java:XccServlet.java

package presentation.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * {@link XxxServlet}
 */
@WebServlet("/xxx")
public class XxxServlet extends HttpServlet {

  /**
   * {@inheritDoc}
   */
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

    ObjectMapper mapper = new ObjectMapper();

    URL url = new URL("https://xxx.yyy.zzz");
    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    // POST, JSON に必要な設定
    urlConnection.addRequestProperty("Content-Type", "application/json; charset=UTF-8");
    urlConnection.setRequestMethod("POST");
    urlConnection.setDoOutput(true);
    urlConnection.setDoInput(true);
    // その他に使うことがある設定
    urlConnection.setRequestProperty("User-Agent", "Android");
    urlConnection.setConnectTimeout(100000);
    urlConnection.setReadTimeout(100000);
    urlConnection.setRequestProperty("Accept-Language", Locale.getDefault().toString());

    try (AutoCloseable closeable = () -> urlConnection.disconnect()) {

      urlConnection.connect();

      // POST する JSON データ
      HashMap<String, Object> map = new HashMap<>();
      map.put("text", "value");
      // POST するデータを書き込み
      try (PrintStream stream = new PrintStream(urlConnection.getOutputStream())) {
        stream.print(mapper.writeValueAsString(map));
      }

      // ステータスコード取得
      if (urlConnection.getResponseCode() != 200) {
        throw new Exception("WebAPI 実行エラー");
      }

      // 取得したJSONデータをレスポンスに設定
      try (InputStream stream = urlConnection.getInputStream()) {
        JsonNode json = mapper.readTree(stream);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        response.getWriter().print(json);
      }

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

```