きり丸アドベントカレンダー2020の7記事目です。
6日目の記事でJava -> HTMLにデータを転送することができました。
しかし、それではデータを取得することしかできません。
今回の記事では、データの更新、削除、追加できるようにHTML -> Javaにデータを転送できるようにします。
ゴール
できない
- 画面の更新結果を知る
手順
TODOの項目追加
現在は、TODOクラスを適当に設計してしまったため、id, userIdしか所持していません。しかし、これではTODOを管理できません。なので、実行すること、という意味を込めて「Action」という項目を追加します。
また、データマッピングする際にSpringにコンストラクタが要求されます。なので、@NoArgsCOnstructor
と@AllArgsConstructor
を設定してください。
ファイル名:TodoDto.java
@Data @Builder @NoArgsConstructor // 引数0のコンストラクタ @AllArgsConstructor // 引数全部のコンストラクタ public class TodoDto { int id; String userId; String action; // 項目を追加 }
HTMLにFormとsubmitボタンを準備する
Action項目を追加します。idやuserIdと異なり、画面で修正したいのでinputのtypeをtextで設計するといいでしょう。
そして、Javaへの転送対象のデータをFormタグで囲みます。actionにはJavaと同じURL、更新するのでmethodはpostが良いでしょう。
その後、Javaへ転送するためのsubmitボタンを追加します。このボタンをクリックすると、formのactionに設定している項目に対してデータを転送します。
転送するデータを設定するためには、inputタグのnameを設定する必要があります。この項目を元にSpringがいいかんじにマッピングしてくれます。idとuserIdは画面で修正させたくなかったので、inputタグのtypeをhiddenにして設定することにします。
ファイル名:index.html
<tr th:each="todo : ${todos}"> <!-- フォームタグ --> <form action="/" method="post"> <td th:text="${todo.id}"></td> <input type="hidden" name="id" th:value="${todo.id}"> <td th:text="${todo.userId}"></td> <input type="hidden" name="userId" th:value="${todo.userId}"> <!-- Actionの項目 --> <td><input type="text" th:value="${todo.action}" name="action"></td> <!-- Submitボタンの追加 --> <td><input type="submit" value="修正"></td> </form> </tr>
Javaでpostを受け取れるようにする
index.htmlでformのmethodをpostにしたため、Javaでは@PostMapping
で受け取れるようにする必要があります。
データを受け取るときは、パラメータに対象のクラスを設定するとSpringが値をマッピングしてくれます。
また、データを更新した後は、redirect:/
とリダイレクト先を指定すると、再度初期画面を表示させることができます。
ファイル名:IndexController.java
@PostMapping("/") public String edit(TodoDto model){ // パラメータ System.out.println(model); System.out.println("修正ボタンクリック"); return "redirect:/"; // リダイレクトで"/"に戻る }
この状態でJavaを再起動すると、データのマッピングができて、かつ、修正ボタンに値を設定できました。
ボタンごとにJavaの送信先メソッドを振り分ける
修正ボタンを追加できました。しかし、同様に削除ボタンを追加すると、修正も削除ボタンも同じJavaのメソッドを呼んでしまいます。なので、なんとかして呼び分ける必要があります。
submitボタンにname属性を付与します。今回は、修正ボタンにはedit、削除ボタンにはdeleteという名前を付与します。
ファイル名:index.html
<tr th:each="todo : ${todos}"> <form action="/" method="post"> <td th:text="${todo.id}"></td> <input type="hidden" name="id" th:value="${todo.id}"> <td th:text="${todo.userId}"></td> <input type="hidden" name="userId" th:value="${todo.userId}"> <td><input type="text" th:value="${todo.action}" name="action"></td> <td><input type="submit" name="edit" value="修正"></td> <!-- editを付与 --> <td><input type="submit" name="delete" value="削除"></td> <!-- inputを追加しつつdeleteを付与--> </form> </tr>
Java側で呼び分けたメソッドを受け取る
@PostMapping
にparamsという属性があるので、そこに対してedit
とdelete
と付与すると呼び分けることができます。
また、パラメータが1つの時は問題ありませんでしたが、複数になったときにはURLに対してはvalue
という変数名を付与する必要があります。
ここまで実施すれば、修正とも、削除とも呼び分けることができます。
ファイル名:IndexController.java
@PostMapping(value="/", params="edit") public String edit(TodoDto model){ System.out.println(model); System.out.println("修正ボタンクリック"); return "redirect:/"; } @PostMapping(value="/", params="delete") public String delete(TodoDto model){ System.out.println(model); System.out.println("削除ボタンクリック"); return "redirect:/"; }
追加ボタンを追加する
修正と削除ボタンの追加ができれば、追加ボタンは難しくありません。ただし、ユーザ名を一意にすることができないので、現在はボタンだけ設置することになります。
ファイル名:index.html
<tr> <form action="/" method="post"> <td></td> <td></td> <td><input type="text" name="action"/></td> <td><input type="submit" name="add" value="追加"/></td> </form> </tr>
ファイル名:IndexController.java
@PostMapping(value="/", params="add") public String add(TodoDto model){ System.out.println(model); System.out.println("追加ボタンクリック"); return "redirect:/"; }
ちなみに本来のメソッドは…
HTMLのformタグのmethodがget,postのみしか対応していないので、この2つを駆使することになります。
本来であれば、追加にはPut、削除にはDeleteのメソッドを使うのが一般的です。今回は特に使いませんが、頭の片隅に入っていると仕事で役に立つかもしれません。
- 取得
- Get
- 更新
- Post
- 追加
- Put
- 削除
- Delete
ソースコード
アドベントカレンダー7日目。
github.com
終わりに
JavaとHTMLの相互のデータ転送ができるようになったので、一つ壁を越えました。このような、JavaとHTMLのような別言語の接続箇所は結構難易度が高い場所です。なので、この接続箇所を綺麗に設計できるかで設計レベルが変わります。私はまだうまく設計できないです。
8日目はデータを登録します。JavaとDBの接続場所になるので、またここも壁となります。
ぜひ、頑張って着手してみて下さい。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
類似記事
きり丸アドベントカレンダー2020 adventar.org
きり丸のherokuページ
https://kirimaru-todoapp.herokuapp.com/
8日目のアドベントカレンダーの記事 https://nainaistar.hatenablog.com/entry/2020/12/08/083000nainaistar.hatenablog.com