Java Spring Boot3 @ModelAttributeを使った入力データの取得

coding programming css 1853305

Controllerのメソッドの引数にRequestParamを羅列することなく、コードの見通しを良くするためにModelAttributeオブジェクトを使ってフォームパラメータを送受信する方法を紹介します。

目次

新規プロジェクトの作成

Intellij IDEAでSpring Initializrを選択し新規プロジェクトを作成します。依存関係として以下を選択します。

  • Spring Boot DevTools
  • Lombok
  • Spring Web
  • Thymeleaf

フォームの内容を受け取るクラスの作成

フォームの入力内容を一つのJavaにまとめ、各入力値に相当するプロパティを定義します。これをフォームクラスと呼びます。

以下にフォームの内容を受け取るフォームクラスを作成します。

package com.example.springboo3samplemodelattribute;

import lombok.Data;

@Data
public class FormData {
    private String name;
    private String password;
    private int gender;
    private int blood;
    private int[] categories;
    private String note;
}

プロパティ名はフォームの部品と同じ名前を用います。

@DataはLombokが提供するアノテーションです。@Dataを指定することで、getterとsetterが自動的に生成されます。Intellij IDEAのgetter/setter自動生成機能と異なり、クラスにコードは生成されません。getter/setter以外にも、デフォルトコンストラクタ、toString()メソッドなども自動生成されます。

以下のようにFormDataのStructureにgetter/setterが追加されていることが確認できます。

Controllerの作成

Controllerを作成します。フォームの要素をFormDataクラスのgetterで取得します。registerメソッド引数に指定するオブジェクトがFormDataModelAndViewの2種類だけになるので大分コードが整理されました。

@RestController
public class FormController {
    @PostMapping("/register")
    public ModelAndView register(
            @ModelAttribute FormData formData,
            ModelAndView mv
    ) {
        StringBuilder sb = new StringBuilder();
        sb.append("Name: " + formData.getName());
        sb.append("Password: " + formData.getPassword());
        sb.append("Gender: " + formData.getGender());
        sb.append("Blood: " + formData.getBlood());
        sb.append("Category: " + Arrays.toString(formData.getCategories()));
        sb.append("Note: " + formData.getNote().replaceAll("\n",""));

        mv.setViewName("result");
        mv.addObject("userData", sb.toString());
        return mv;
    }
}

フォームクラスを使用しなかった場合のコードを比較のために以下に記載します。

@Controller

public class HelloController {
    @PostMapping("/register")
    public ModelAndView register(
            @RequestParam("name") String name,
            @RequestParam("password") String password,
            @RequestParam("gender") int gender,
            @RequestParam("blood") int blood,
            @RequestParam("category") int[] categories,
            @RequestParam("note") String note,
            ModelAndView mv
    ) {
        StringBuilder sb = new StringBuilder();
        sb.append("Name: " + name);
        sb.append("Password: " + password);
        sb.append("Gender: " + gender);
        sb.append("Blood: " + blood);
        sb.append("Category: " + Arrays.toString(categories));
        sb.append("Note: " + note.replaceAll("\n",""));

        mv.setViewName("result");
        mv.addObject("userData", sb.toString());
        return mv;
    }
}

入力フォームの作成

静的HTMLで以下のファイルを作成します。

このファイルはThymeleafテンプレートではなく、静的HTMLですので、保存先は

以下になります。

src/main/resources/static/form.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>入力フォーム</title>
</head>
<body>
<form action="register" method="post">
    <table>
        <tr>
            <td>Name</td>
            <td>
                <input type="text" name="name">
            </td>
        </tr>
        <tr>
            <td>Password</td>
            <td>
                <input type="password" name="password">
            </td>
        </tr>
        <tr>
            <td>Gender</td>
            <td>
                <input type="radio" name="gender" value="1">男性
                <input type="radio" name="gender" value="2">女性
                <input type="radio" name="gender" value="0">回答したくない
            </td>
        </tr>
        <tr>
            <td>血液型</td>
            <td>
                <select name="blood">
                    <option value="1">A型</option>
                    <option value="2">B型</option>
                    <option value="3">AB型</option>
                    <option value="4">O型</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>カテゴリ</td>
            <td>
                <input type="checkbox" name="category" value="1">金融
                <input type="checkbox" name="category" value="2">製造業
                <input type="checkbox" name="category" value="3">サービス業
                <input type="checkbox" name="category" value="4">通信
                <input type="checkbox" name="category" value="g">その他
            </td>
        </tr>
        <tr>
            <td>メモ</td>
            <td>
                <textarea name="note" rows="4" cols="90"></textarea>
            </td>
        </tr>
    </table>
    <input type="submit" value="送信">
</form>
</body>
</html>

結果表示用テンプレートの作成

以下にThyemeleafテンプレートファイルを作成します。

src/main/resources/templates/result.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>Result</title>
</head>
<body>
<span th:text="${userData}"></span>
</body>
</html>

実行

それではブラウザからアクセスしてみます。

入力フォームに適当に値を入力して送信ボタンをクリックします。

結果が正しく表示されました。

よかったらシェアしてね!
目次