Formのバインドについて

本日のお題

本日のお題は、フォームのバインドについてです。

目次

  • フォームのバインドとは
  • クラスの作成
  • コントローラの編集〜getSignup編
  • ビューの編集
  • コントローラの編集〜postSignup編

フォームのバインドとは

フォームのバインドとは、フォームのname属性をキーとして入力内容をコントローラで取り出すための処理のことです。

例えば、RailsやLaravelであれば以下のような処理でフォームの内容を簡単に取り出すことができていました。

Rails: params[:age]

Laravel: $request->input("age");

これは、この記述だけで意図したものを取り出せるようにあらかじめフレームワークの側でプログラムが組まれているためなのですが、Spring Bootではこの記述をある程度自分自身で行う必要があります。

 

以下、順番にそのための作業をしていきます。

クラスの作成

まず、フォームの内容を管理するためのJavaクラスを作ります。

今回は、サインアップフォームを作成するので、demo(アプリ名)/applicationディレクトリにform/SignupForm.javaを作ります。

 

ここではまず、フォームで入力してもらいたい要素(ユーザー名や年齢など)を、SignupFormクラスのインスタンスフィールド化します。

ーーSignupForm.javaーー

package com.example.demo.apprication.form.SignupForm;

import lombok.Data;

import java.util.Date;

import org.springframework.format.annotation.DateTimeFormat;

 

@Data

public class SignupForm{
    private String userId;

    private String userName;

    private String password;

    @DateTimeFormat(pattern = "yyyy/mm/dd")

    private Date birthday;

    private Integer age;

    private Integer gender;

}

 

ポイントになってくるのは、赤線部分の2行ですね。

前半の@DateTimeFormat(pattern = "yyyy/mm/dd")は、指定したフォーマットで入力された文字列をDate型に変換してくれる役割を持っています。

例えばフォームで"1990/01/01"と入力しても、そのままだと"1990/01/01"という文字列(Stirng型)として記録されてしまいます。

ですがこのアノテーションをつけることによって、直後に定義しているbirthdayというインスタンスフィールドに対して、"yyyy/mm/dd"形式の文字列がDate型に変換された状態でセットされるようになります。

コントローラの修正〜getSignup編

フォームを定義するモデルが定義できたので、コントローラを修正します。

まずは、フォームのある画面に遷移するためのgetSingupメソッドを修正します。

 

importの追加

import org.springframework.web.bind.annotation.ModelAttribute;

import com.example.demo.application.form.SignupForm;

import lombok.exterm.slf4j.Slf4j;

 

getSignupメソッドの編集

public String getSignup(Model model, Locale locale, @ModelAttribute SignupForm form){

    // メソッドの中身はそのままでOK

}

 

ポイント

ポイントは、引数として追加されている@ModelAttribute SignupForm formですね。

これを追加することで、以下の作業を自動で行ってくれています。

model.addAttribute("signupForm", form);

つまり、先程SignupFormクラスで定義した内容からformというインスタンスを作り、それをsignupFormというキーでビューに渡せるようにしてくれているのですね。

 

次に、このsignupFormの内容をビューで表示できるようにしていきます。

ビューの編集

ビューの編集のポイントは、object属性とfield属性を使うということです。

どちらもthymeleaf専用の属性ですね。

以下、使用例です。

<form th:object="${signupForm}" .....>

    <input type="text" th:field="*{userName}" ....>

    .....以下略.....

 

まず、form要素に対してth:object="{$signupForm}"としてこのフォームをどのクラスにバインドするのかを指定します。

次に、<input th:field="*{userName}"として、各フォーム部品をバインド先のクラスのどのインスタンスフィールドに対応させるのかを指定します。

$ではなく*を用いているところに注意してください。

これで、フォームに入力された値をコントローラで受け取れるようになりました。

 

th:fieldについての補足

th:field="*{userName}"とした場合、name="userName" id="userName"に変換されてビューに表示されます。

コントローラの編集〜postSignupメソッド編

ビューができたので、次にフォームの内容をコントローラで受け取れるようにしていきます。

以下のようにメソッドを編集します。

// 引数を追加

public String postSignup(@ModelAttribute SignupForm form){

    一旦は、フォームの内容をログで出力

    log.info(form.toString());

    return "redirect: /login";

}

 

本来ならば、受け取ったパラメータをDBに保存する処理を書くのですが、一旦はログ出力してどのような形でパラメータが送信されているのかを見てみます。

ちなみに、このlog.infoメソッドは、@slf4jアノテーションを用いることで使用可能になります。

 

フォームから受け取った内容

 SignupForm(userId=213399, password=0000000a, userName=test, birthday=Mon Jan 01 00:00:00 JST 1990, age=31, gender=1)

フォームから受け取った内容は以上のようになっています。

終わりに

とりあえずこれで、フォームに入力された値を受け取ることが可能になりました。

本来であればこのあとはDBへの登録処理などを記述していくのですが、その前に次回ではバリデーションを設定していきたいと思います。