JSONを使用してJava ServletからiPhoneアプリへ値を受け渡してみる

　会社の同期に誘われてiPhoneアプリを作成している最中、WebサーバーとiPhoneアプリ間の値の受渡しをどうするか悩んでいました。その時、どうやらJSONを使用して、値を受け渡すらしい！ということを知りました。
　そこで、色々調べた結果、無事にJSONを使用した値の受渡しができたので、まとめます。

　新人研修&自己学習で得た知識で書いてるので、間違っている箇所やより良い方法があれば、コメントください、、、、

#作成するアプリ
　画面としては、こんなかんじです。
![スクリーンショット 2020-05-12 22.47.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632247/36f105b4-04bd-7d6f-3949-4d7562109f32.png)

　流れとしてはこんな感じです。
　①　「JSONを取得する」ボタンを押し、JavaServletへランダムな数値を渡す。
　②　JavaServletは、受け取った数値に応じたJSONをレスポンスする。
　③　Swiftは、受け取ったJSONオブジェクトを変換し、値を画面へ出力する。

　赤枠で囲まれている箇所に、JavaServletから得たJSONを出力しています。
　また、すべてローカル環境で実装します。

#環境
　XcodeとEclipseを使用し、開発しました。　
　
　JSONを使用するにあたって、GSONかJacksonで迷いましたが、今回はJacksonを使用しました。
　EclipceでのJackson のセットアップ方法は以下を参考にしました。
　https://tech.pjin.jp/blog/2020/03/09/jackson_setup/

#実際のコード
##Xcode
JSONを取得する画面

```Swift:ViewController.swift

import UIKit

class ViewController: UIViewController {
    //表示用の文言
    var textId = ""
    var textName = ""
    
    //タプル配列の宣言
    var studentList:[(id:String , name:String)] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    @IBAction func getJson(_ sender: Any) {
        self.performSegue(withIdentifier: "goResultVC", sender: nil)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {   
        //リクエストURL　JSONを返すサーブレットを指定
        guard let req_url = URL(string: "http://localhost:8080/servlet_test/JsonServlet")
            else{return}
        //リクエストに必要な情報を生成
        var req = URLRequest(url: req_url)
        //0~2のランダムな数値を取得
        let id = Int.random(in: 0...2)
        //データ転送を管理するためのセッションを作成
        let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main)
        //JavaServletへ渡す情報（ID）をBodyへ設定する
        req.httpMethod = "POST"
        req.httpBody = "id=\(id)".data(using: .utf8)
        //リクエストをタスクとして登録
        let task = session.dataTask(with: req, completionHandler: {
            (data, response ,error) in
            //セッションの終了
            session.finishTasksAndInvalidate()
            do{
                //取得したJSONを変換する
                let decoder = JSONDecoder()
                let json = try decoder.decode(StudentJson.self, from: data!)

                self.textId = json.id!
                self.textName = json.name!
                
                //「JSONを取得する」ボタンに紐づくセグエ
                if segue.identifier == "goResultVC" {
                    let nextVC = segue.destination as! ResultViewVontroller
                    nextVC.jsonId = self.textId
                    nextVC.jsonName = self.textName
                }
                
            }catch{
                print(error)
                print("エラーがでました")
            }
        })
        //ダウンロード開始
        task.resume()
    }
    //JSONのデータ構造
    struct  StudentJson: Codable {
        let id: String?
        let name: String?
    }
}
```

JSONを出力する画面

```Swift:ResultViewVontroller.swift
import UIKit

class ResultViewVontroller: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    //出力メッセージのフィールド
    var jsonId = ""
    var jsonName = ""
    //出力ラベル
    @IBOutlet weak var resultJsonId: UILabel!
    @IBOutlet weak var resultJsonName: UILabel!
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        resultJsonId.text = jsonId
        resultJsonName.text = jsonName
    }   
}
```

##Eclipse

Java Servlet

```java:JsonServlet.java
 package servlet;

import java.io.IOException;

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.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import bean.JsonBean;

/**
 * Servlet implementation class JsonServlet
 */
@WebServlet("/JsonServlet")
public class JsonServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public JsonServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		JsonBean jsonBeanList[] = new JsonBean[3];
		//Javaオブジェクトに値をセット
        JsonBean jsonBean = new JsonBean();
        jsonBean.setId("101");
        jsonBean.setName("tanaka");
        JsonBean jsonBean2 = new JsonBean();
        jsonBean2.setId("102");
        jsonBean2.setName("yamada");
        JsonBean jsonBean3 = new JsonBean();
        jsonBean3.setId("103");
        jsonBean3.setName("satou");
        jsonBeanList[0] = jsonBean;
        jsonBeanList[1] = jsonBean2;
        jsonBeanList[2] = jsonBean3;

        //
        String str = request.getParameter("id");
        int requestId = Integer.parseInt(str);

        System.out.println(requestId);

        ObjectMapper mapper = new ObjectMapper();
        try {
            //JavaオブジェクトからJSONに変換
            String testJson = mapper.writeValueAsString(jsonBeanList[requestId]);

            //JSONの出力
            response.getWriter().write(testJson);
            //出力されるJSONの確認
            System.out.println(testJson);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
	}
}
```

Bean

```java:JsonBean.java
package bean;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonProperty;

public class JsonBean {

    @JsonProperty("id")
    private String id;

    @JsonProperty("name")
    private String name;

    public void setId(String id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

}
```

JsonServletの動きを確認するには、Chromeの拡張機能であるTalend API Testerがおすすめです！
[Talend API Tester](https://chrome.google.com/webstore/detail/talend-api-tester-free-ed/aejoelaoggembcahagimdiliamlcdmfm?hl=ja)

#まとめ
これで、フロントエンドとバックエンド間の通信ができるようになりました。
次は、AWS上に乗っけてみます。

また、今回の実装をするにあたり、多くのQiita記事と書籍を参考にしました。

拙い内容でしたが、閲覧いただきありがとうございました！

マークダウン記法、めちゃめちゃ書きやすいですね。