◀ 10.

ビューから値をモデルに格納しコントローラーで受け取る方法

▶
この記事の要点
  • Spring MVC のビュー → モデル → コントローラのデータフロー
  • ビュー (HTML): <form> の input 要素に name 属性 = モデルフィールド名
  • モデル: form クラス(POJO)の getter/setter で受け取る
  • コントローラ: メソッド引数に form クラスを宣言すると自動バインド

 

本稿はSpring Frameworkにおいてビュー→モデル→コントローラーに値を渡す方法を説明します。

 

ビュー

inputのnameからフォームプロパティへバインドし検証後にコントローラで受け取る図

元のフォーム・モデル・コントローラの例は以下に残しています。モデルのgetter/setterの未定義名だけを訂正しました。ここでいうモデルは入力を受け取るフォームオブジェクトで、DBへ保存済みのEntityを意味しません。

<form action="index" method="get">
  
 <input id="userId" type="text" name="userId"/>
    <button type="submit">ボタン</button>
</form>

 

モデル

public class UserModel {

    private String userId;
    
    public String
getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }
}

 

コントローラー

@Controller
public class IndexController {

    @ModelAttribute
    UserModel userModel() {
        return new UserModel();
    }

    
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public void index(
@ModelAttribute UserModel userModel){

        String userId = userModel.getUserId();
        
        ...
        
    }
}

 

name属性とJavaプロパティの対応

位置値・役割
inputのnameuserId。送信されるパラメータ名
inputのid画面側で要素を識別する名前。nameの代用にはならない
フォームuserIdフィールドとsetUserId/getUserId
コントローラ受け取ったフォームからgetUserId()で値を取得

元のGETフォームでは/index?userId=Taroのようなクエリから値を受け取ります。action="index"は相対URLなので、画面の位置やアプリのコンテキストパスも確認してください。JSON本文を送るAPIの@RequestBodyとは別の仕組みです。

コンパイル・バインドを確認した独立例

Spring Framework 6.2.12 / Java 21で、次の3ファイルを同じexampleパッケージに置き、MockMvcとDataBinderで検証しました。旧コードへ新しい依存を混ぜて貼る例ではありません。既存アプリには、その版の依存・コントローラ検出・MVC設定を確認して組み込んでください。

UserModel.java

package example;

public class UserModel {
    private String userId;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }
}

UserModelValidator.java

package example;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

public class UserModelValidator implements Validator {
    @Override
    public boolean supports(Class<?> type) {
        return UserModel.class.isAssignableFrom(type);
    }

    @Override
    public void validate(Object target, Errors errors) {
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userId", "required");
        String value = ((UserModel) target).getUserId();
        if (value != null && value.length() > 40) {
            errors.rejectValue("userId", "tooLong");
        }
    }
}

この例の仕様は「userIdは空白だけでなく、40文字以内」です。実システムのID形式・存在確認・権限確認とは別なので、業務仕様に合わせて変更します。

IndexController.java

package example;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class IndexController {
    @InitBinder("userModel")
    public void configure(WebDataBinder binder) {
        binder.setAllowedFields("userId");
        binder.setValidator(new UserModelValidator());
    }

    @GetMapping("/index")
    @ResponseBody
    public ResponseEntity<String> index(
            @Validated @ModelAttribute("userModel") UserModel form,
            BindingResult result) {
        if (result.hasErrors() || result.getSuppressedFields().length > 0) {
            return ResponseEntity.badRequest().body("invalid input");
        }
        return ResponseEntity.ok()
                .header("Content-Type", "text/plain;charset=UTF-8")
                .body(form.getUserId());
    }
}

InitBinderはuserModelへのプロパティバインドをuserIdだけに限定します。Validatedで登録したValidatorを呼び、直後のBindingResultでエラーを受け取ります。この例は許可外キーが除外された場合も400で拒否する設計です。すべてのSpringアプリが余分なキーで自動的に400になるわけではありません。

成功時は確認用にuserIdをtext/plainで返し、DBへ保存しません。画面のHTMLへ表示する実アプリではテンプレートのエスケープを維持してください。元のvoidコントローラとは違って確認用レスポンスを明示しています。旧void例ではビュー名の解決と対応テンプレートが別途必要です。

検証した受け取り結果

入力結果
userId=Taro200、本文Taro
userIdなし・空白のみ・41文字400、検証失敗
id=Taro400。userIdの代わりにはならない
userId=TaroとisAdmin=true許可外キーを検出し400
HTMLのような文字列text/plainとして返す。HTMLとして実行しない

受け取れないときと安全上の注意

  1. 送信先URL・HTTPメソッド・inputのnameを確認する。disabledの入力など、送信されない項目にも注意する。
  2. フィールド、getter、setter、ModelAttribute名、InitBinderの対象名を照合する。
  3. BindingResultの配置、検証失敗、除外されたフィールドを確認する。秘密情報を入力全体ごとログへ出さない。
  4. 値のバインドはログイン・所有者確認・DB保存を代行しない。永続化用Entityを直接バインドしない。
  5. GETは今回の読み取り確認用。更新を伴う処理は適切なメソッドとCSRF対策・認可・保存時の失敗処理を別途設計する。

今回の8テストはコンパイル、getter/setter、SpringのMockMvc/バインド/検証までです。実ブラウザからのフォーム送信、認証/CSRFフィルタ、ビュー描画、DB保存を含む本番アプリ全体は未検証です。

公式資料: Spring 6.2のModelAttribute、Data Binding(2026年10月確認)。

子ページ

子ページはありません

同階層のページ
  1. インストール(eclipseプラグイン)
  2. クイックスタート
  3. プロジェクトの作成
  4. Spring Bootプロジェクトの作成
  5. Spring Bootプロジェクトの実行
  6. Spring BootでHello World!
  7. アノテーション一覧
  8. DB接続設定からエンティティおよびリポジトリの作成、値の取得まで(JPA編)
  9. DB接続設定や値の取得(JdbcTemplate編)
  10. ビューから値をモデルに格納しコントローラーで受け取る方法
  11. コントローラーにてモデルに値を格納してビューに渡す方法
  12. テンプレートエンジン
  13. ModelとModelAndViewの違い
  14. AOPの使用方法
  15. classpath: 内部ファイルの読み込み
  16. file: 外部ファイルの読み込み
  17. CSVファイルアップロード方法(Ajax)
  18. CSVファイルダウンロード方法(Ajax)
  19. Spring Bootプロジェクトのビルドと本番環境へのデプロイ方法(内部tomcat使用)
  20. Application.propertiesの環境依存設定の分割方法
  21. JPAにおけるEntityManagerの取得方法
  22. JPAにおけるjava.sql.Connectionの取得方法
  23. エラー一覧
  24. jarの引数を受け取る方法
  25. Spring BootでGmailからメール送信
  26. 複数のDBに接続する設定(Spring Boot & JPA編)
  27. ポート番号の変更
  28. Basic認証の実装と特定のURLに限定する方法
  29. Spring SecurityのBasic認証の無効化
  30. 独自のエラーページを定義する方法
  31. プロパティファイルの値やjar実行時の引数を取得する方法