きり丸の技術日記

技術・エンジニアのイベント・資格等はこちらにまとめる予定です

HTMLからJavaにパラメータを渡す(SpringBoot)

きり丸アドベントカレンダー2020の7記事目です。


6日目の記事でJava -> HTMLにデータを転送することができました。

しかし、それではデータを取得することしかできません。

今回の記事では、データの更新、削除、追加できるようにHTML -> Javaにデータを転送できるようにします。

ゴール

  • 画面から送信したデータがJavaに受け取れることを確認する
  • 更新、削除、追加の3つのイベントを分けて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という属性があるので、そこに対してeditdeleteと付与すると呼び分けることができます。

また、パラメータが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

f:id:nainaistar:20201109133010p:plain