kazpgmの日記

『プログラム自動作成@自動生成』作成の日記

フロント側をFlutter(スマホ)Thymeleaf(PC)、バックエンド側SpringBootの自動作成勉強中

14:22
①4月8日からのつづき。バックエンドSpring側を修正している。
17:04
①フロントFlutter側、バックエンドSpring側がうまく動いた。
②フロントFlutter側
■修正後のuser_form.dart

import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter_app/form/user_err_form.dart';
import 'comm/message_form.dart';

/// ユーザー情報画面Form
class UserForm {
  //プロパティ 入出力データ用
  late int id; // ID
  late String name; // 名前
  late String email; // メールアドレス
  late String password; // パスワード
  late String passwordConfirm; // パスワード確認
  late List<String> rolesArray; // ロール
  late String roles; // ロール (詳細表示用)
  // バックエンド(SpringBoot)のFormでBooleanだけどStringで処理する
  late String enableFlag; // 可否フラグ
  //プロパティ エラーメッセージ
  late UserErrForm userErrForm; // プロパティ エラーメッセージ
  // 共通・メッセージ
  late MessageForm messageForm; // 共通・メッセージ

  /// コンストラクタ
  // Dartでは「コンストラクタ名.任意名称」で複数のコンストラクタを定義する
  // 「クラス名(this.name,・・・);」コンストラクタはいらないので,
  // これだけにする。
  // 初期値のクラスを作成している
  UserForm.initData()  {
    //入出力データ用
    id = 0;
    name = "";
    email = "";
    password = "";
    passwordConfirm = "";
    rolesArray = <String>[];
    roles = "";
    enableFlag = "";
    // プロパティ エラーメッセージ
    userErrForm = UserErrForm.initData();
    // 共通・メッセージ
    messageForm = MessageForm.initData();
  }

  /// HTTPレスポンスデータを反映する
  fromJson(String resData) {
    Map<String,dynamic> _resDataMap =
              jsonDecode(resData);
    //入出力データ用
    if (_resDataMap["userForm"]==null) {
      id = 0;
      name = "";
      email = "";
      password = "";
      passwordConfirm = "";
      rolesArray = <String>[];
      roles = "";
      enableFlag = "";
    } else {
      id = _resDataMap["userForm"]["id"] ?? 0;
      name = _resDataMap["userForm"]["name"] ?? "";
      email = _resDataMap["userForm"]["email"] ?? "";
      password = _resDataMap["userForm"]["password"] ?? "";
      passwordConfirm = _resDataMap["userForm"]["passwordConfirm"] ?? "";
      //jsonから読み込んだときのエラー(”type 'List<dynamic>' is not a subtype of type 'List<String>'”)に
      // 対応し、".cast<String>()"でキャストした
      rolesArray = _resDataMap["userForm"]["rolesArray"]!=null?_resDataMap["userForm"]["rolesArray"].cast<String>():<String>[];
      roles = _resDataMap["userForm"]["roles"] ?? "";
      enableFlag = "";
      if (_resDataMap["userForm"]["enableFlag"] != null) {
        if (_resDataMap["userForm"]["enableFlag"]) {
          enableFlag = "true";
        } else {
          enableFlag = "false";
        }
      }
    }
    // プロパティ エラーメッセージ
    userErrForm.fromJson(resData);
    // 共通・メッセージ
    messageForm.fromJson(resData);
  }

  /// HTTPレスポンスデータを作成する
  Map<String,dynamic> toJsonMap (String _mode, String _csrf, int page) {
    Map<String,dynamic> userFormMap = {
      'id': id,
      'name': name,
      'email': email,
      'password': password,
      'passwordConfirm': passwordConfirm,
      'rolesArray': rolesArray,
      'enableFlag': enableFlag,
    };
    Map<String,dynamic> rtnMap = {
      'userForm': userFormMap,
      'formComm': messageForm.toJsonMap(_mode, _csrf, page),
    };
    return rtnMap;
  }

  /// http.postのbodyで使用するJsonデータを返却する
  String toJson(String _mode, String _csrf, [int page=1]) {
    return json.encode(toJsonMap(_mode, _csrf, page));
  }

  /// 入出力データを、TextFormFieldに設定する
  forUserFormController(
      TextEditingController nameController,
      TextEditingController emailController,
      TextEditingController passwordController,
      TextEditingController passwordConfirmController
      ) {
    nameController.text = name;
    emailController.text = email;
    passwordController.text = password;
    passwordConfirmController.text = passwordConfirm;
  }

  /// TextFormField値を、入出力データに設定する
  fromUserFormController(
      TextEditingController nameController,
      TextEditingController emailController,
      TextEditingController passwordController,
      TextEditingController passwordConfirmController
      ) {
    name = nameController.text;
    email = emailController.text;
    password = passwordController.text;
    passwordConfirm = passwordConfirmController.text;
  }
}

■修正後のuser_err_form.dart

import 'dart:convert';

/// ユーザー情報画面プロパティ エラーメッセージ用Form
class UserErrForm {
  //プロパティ エラーメッセージ用
  late List<String> idErr; // ID
  late List<String> nameErr; // 名前
  late List<String> emailErr; // メールアドレス
  late List<String> passwordErr; // パスワード
  late List<String> passwordConfirmErr; // パスワード確認
  late List<String> checkPasswordPasswordConfirmErr; // パスワード、パスワード確認の相関チェック
  late List<String> rolesArrayErr; // ロール
  late List<String> enableFlagErr; // 可否フラグ

  /// コンストラクタ
  // Dartでは「コンストラクタ名.任意名称」で複数のコンストラクタを定義する
  // 「クラス名(this.name,・・・);」コンストラクタはいらないので,
  // これだけにする。
  // 初期値のクラスを作成している
  UserErrForm.initData()  {
    //エラーメッセージ用
    idErr = <String>[];
    nameErr = <String>[];
    emailErr = <String>[];
    passwordErr = <String>[];
    passwordConfirmErr = <String>[];
    checkPasswordPasswordConfirmErr = <String>[];
    rolesArrayErr = <String>[];
    enableFlagErr = <String>[];
  }

  /// HTTPレスポンスデータを反映する
  fromJson(String resData) {
    Map<String,dynamic> _resDataMap =
              jsonDecode(resData);
    //エラーメッセージ用
    if (_resDataMap["resErrorData"]==null) {
      idErr = <String>[];
      nameErr = <String>[];
      emailErr = <String>[];
      passwordErr = <String>[];
      passwordConfirmErr = <String>[];
      checkPasswordPasswordConfirmErr = <String>[];
      rolesArrayErr = <String>[];
      enableFlagErr = <String>[];
    } else {
      idErr = _resDataMap["resErrorData"]["userForm.id"]!=null?_resDataMap["resErrorData"]["userForm.id"].cast<String>():<String>[];
      nameErr = _resDataMap["resErrorData"]["userForm.name"]!=null?_resDataMap["resErrorData"]["userForm.name"].cast<String>():<String>[];
      emailErr = _resDataMap["resErrorData"]["userForm.email"]!=null?_resDataMap["resErrorData"]["userForm.email"].cast<String>():<String>[];
      passwordErr = _resDataMap["resErrorData"]["userForm.password"]!=null?_resDataMap["resErrorData"]["userForm.password"].cast<String>():<String>[];
      passwordConfirmErr = _resDataMap["resErrorData"]["userForm.passwordConfirm"]!=null?_resDataMap["resErrorData"]["userForm.passwordConfirm"].cast<String>():<String>[];
      checkPasswordPasswordConfirmErr = _resDataMap["resErrorData"]["userForm.checkPasswordPasswordConfirm"]!=null?_resDataMap["resErrorData"]["userForm.checkPasswordPasswordConfirm"].cast<String>():<String>[];
      rolesArrayErr = _resDataMap["resErrorData"]["userForm.rolesArray"]!=null?_resDataMap["resErrorData"]["userForm.rolesArray"].cast<String>():<String>[];
      enableFlagErr = _resDataMap["resErrorData"]["userForm.enableFlag"]!=null?_resDataMap["resErrorData"]["userForm.enableFlag"].cast<String>():<String>[];
    }
  }
}

■修正後のmessage_form.dart

import 'dart:convert';

/// 共通・メッセージForm
class MessageForm {
  //プロパティ 実行結果メッセージ用
  late String itemErrorMessages; // 項目エラーメッセージ
  late String errorMessage; // 実行結果エラーメッセージ
  late String successMessage; // 実行結果OKメッセージ
  //そのた
  late String mode; // モード
  late int page; // ページ番号
  late int pageObjSize; // 検索結果の当ページの行数
  late int pageObjTotalPages; //  検索結果の総ページ数

  /// コンストラクタ
  // Dartでは「コンストラクタ名.任意名称」で複数のコンストラクタを定義する
  // 「クラス名(this.name,・・・);」コンストラクタはいらないので,
  // これだけにする。
  // 初期値のクラスを作成している
  MessageForm.initData() {
    //実行結果メッセージ用
    itemErrorMessages = "";
    errorMessage = "";
    successMessage = "";
    //そのた
    mode = "";
    page = 1;
    pageObjSize = 0;
    pageObjTotalPages = 0;
  }

  /// http.postのbodyで使用するJsonデータを返却する
  String toJson(String _mode, String _csrf, [int page=1]) {
    return json.encode(toJsonMap(_mode, _csrf, page));
  }

  /// HTTPレスポンスデータを反映する
  fromJson(String resData) {
    Map<String,dynamic> _resDataMap =
              jsonDecode(resData);
    //実行結果メッセージ用
    itemErrorMessages = _resDataMap["itemErrorMessages"] ?? "";
    errorMessage = _resDataMap["errorMessage"] ?? "";
    successMessage = _resDataMap["successMessage"] ?? "";
    //そのた
    mode = _resDataMap["formComm"]["mode"] ?? "";
    Map<String,dynamic> pageObj; // 検索結果のページ情報
    if (_resDataMap["pageObj"]==null || _resDataMap["pageObj"].length < 1) {
      pageObj = {};
      page = _resDataMap["formComm"]["page"] ?? 1;
      pageObjSize = 0;
      pageObjTotalPages = 0;
    } else {
      pageObj = _resDataMap["pageObj"];
      page = pageObj["pageNumber"] + 1;
      pageObjSize = pageObj["size"];
      pageObjTotalPages = pageObj["totalPages"];
    }
  }

  /// HTTPレスポンスデータを作成する
  Map<String,dynamic> toJsonMap (String _mode, String _csrf, int page) {
    Map<String,dynamic> rtnMap = {
      'mode': _mode,
      '_csrf': _csrf,
      'page': page,
    };
    return rtnMap;
  }

}

■修正後のuser_srch_form.dart

import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter_app/form/comm/srch_order_form.dart';
import 'package:flutter_app/form/user_srch_err_form.dart';

import 'comm/message_form.dart';

/// ユーザー情報検索画面Form
class UserSrchForm {
  //プロパティ 入出力データ用
  late String name; // 名前
  late String email; // メールアドレス
  late String roles; // ロール
  late String enableFlag; // 可否フラグ
  late List<dynamic> resListForm; // 情報一覧
  // プロパティ エラーメッセージ
  late UserSrchErrForm userSrchErrForm; // プロパティ エラーメッセージ
  // 共通・検索ソート順Form
  late SrchOrderForm srchOrderForm; // 共通・検索ソート順Form
  // 共通・メッセージ
  late MessageForm messageForm; // 共通・メッセージ

  /// コンストラクタ
  // Dartでは「コンストラクタ名.任意名称」で複数のコンストラクタを定義する
  // 「クラス名(this.name,・・・);」コンストラクタはいらないので,
  // これだけにする。
  // 初期値のクラスを作成している
  UserSrchForm.initData() {
    //入出力データ用
    name = "";
    email = "";
    roles = "";
    enableFlag = "";
    //出力データ用
    resListForm = [{}];
    // プロパティ エラーメッセージ
    userSrchErrForm = UserSrchErrForm.initData();
    // 共通・検索ソート順Form
    srchOrderForm = SrchOrderForm.initData();
    // 共通・メッセージ
    messageForm = MessageForm.initData();
  }

  /// HTTPレスポンスデータを反映する
  fromJson(String resData) {
    Map<String,dynamic> _resDataMap =
              jsonDecode(resData);
    //入出力データ用
    if (_resDataMap["userSrchForm"]==null) {
      name = "";
      email = "";
      roles = "";
      enableFlag = "";
    } else {
      name = _resDataMap["userSrchForm"]["name"] ?? "";
      email = _resDataMap["userSrchForm"]["email"] ?? "";
      roles = _resDataMap["userSrchForm"]["roles"] ?? "";
      enableFlag = _resDataMap["userSrchForm"]["enableFlag"] ?? "";
    }
    //出力データ用
    if (_resDataMap["resListForm"]==null) {
      resListForm = [{}];
    } else {
      resListForm = _resDataMap["resListForm"];
    }
    // プロパティ エラーメッセージ
    userSrchErrForm.fromJson(resData);
    // 共通・検索ソート順Form
    srchOrderForm.fromJson(resData);
    // 共通・メッセージ
    messageForm.fromJson(resData);
   }

  /// HTTPレスポンスデータを作成する
  Map<String,dynamic> toJsonMap (String _mode, String _csrf, [int page=1]) {
    Map<String,dynamic> userSrchFormMap = {
      'name': name,
      'email': email,
      'roles': roles,
      'enableFlag': enableFlag,
    };
    Map<String,dynamic> rtnMap = {
      'userSrchForm': userSrchFormMap,
      'srchOrderForm': srchOrderForm.toJsonMap(_mode, _csrf, page),
      'formComm': messageForm.toJsonMap(_mode, _csrf, page),
    };
    return rtnMap;
  }

  /// http.postのbodyで使用するJsonデータを返却する
  String toJson(String _mode, String _csrf, [int page=1]) {
    return json.encode(toJsonMap(_mode, _csrf, page));
  }

  /// 入出力データを、TextFormFieldに設定する
  forUserSrchFormController(
      TextEditingController nameController,
      TextEditingController emailController,
      ) {
    nameController.text = name;
    emailController.text = email;
  }

  /// TextFormField値を、入出力データに設定する
  fromUserSrchFormController(
      TextEditingController nameController,
      TextEditingController emailController,
      ) {
    name = nameController.text;
    email = emailController.text;
  }
}

■修正後のuser_srch_err_form.dart

import 'dart:convert';

/// ユーザー情報画面プロパティ エラーメッセージ用Form
class UserSrchErrForm {
  //プロパティ エラーメッセージ用
  late List<String> nameErr; // 名前
  late List<String> emailErr; // メールアドレス
  late List<String> rolesErr; // ロール
  late List<String> enableFlagErr; // 可否フラグ

  /// コンストラクタ
  // Dartでは「コンストラクタ名.任意名称」で複数のコンストラクタを定義する
  // 「クラス名(this.name,・・・);」コンストラクタはいらないので,
  // これだけにする。
  // 初期値のクラスを作成している
  UserSrchErrForm.initData()  {
    //エラーメッセージ用
    nameErr = <String>[];
    emailErr = <String>[];
    rolesErr = <String>[];
    enableFlagErr = <String>[];
  }

  /// HTTPレスポンスデータを反映する
  fromJson(String resData) {
    Map<String,dynamic> _resDataMap =
              jsonDecode(resData);
    //エラーメッセージ用
    if (_resDataMap["resErrorData"]==null) {
      nameErr = <String>[];
      emailErr = <String>[];
      rolesErr = <String>[];
      enableFlagErr = <String>[];
    } else {
      nameErr = _resDataMap["resErrorData"]["userSrchForm.name"]!=null?_resDataMap["resErrorData"]["userSrchForm.name"].cast<String>():<String>[];
      emailErr = _resDataMap["resErrorData"]["userSrchForm.email"]!=null?_resDataMap["resErrorData"]["userSrchForm.email"].cast<String>():<String>[];
      rolesErr = _resDataMap["resErrorData"]["userSrchForm.roles"]!=null?_resDataMap["resErrorData"]["userSrchForm.roles"].cast<String>():<String>[];
      enableFlagErr = _resDataMap["resErrorData"]["userSrchForm.enableFlag"]!=null?_resDataMap["resErrorData"]["userSrchForm.enableFlag"].cast<String>():<String>[];
    }
  }
}

■修正後のsrch_order_form.dart

import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter_app/form/comm/message_form.dart';
import 'package:flutter_app/form/comm/srch_order_err_form.dart';

/// 共通・検索ソート順Formのベースクラス
class SrchOrderForm {
  //プロパティ 入出力データ用
  late String sortItemName;
  late String sortOrder;
  late String updMode;
  // プロパティ エラーメッセージ
  late SrchOrderErrForm srchOrderErrForm; // プロパティ エラーメッセージ

  /// コンストラクタ
  // Dartでは「コンストラクタ名.任意名称」で複数のコンストラクタを定義する
  // 「クラス名(this.sortItemName,・・・);」コンストラクタはいらないので,
  // これだけにする。
  // 初期値のクラスを作成している
  SrchOrderForm.initData() {
    //入出力データ用
    sortItemName = "";
    sortOrder = "";
    updMode = "lstMode";
    // プロパティ エラーメッセージ
    srchOrderErrForm = SrchOrderErrForm.initData();
  }

  /// HTTPレスポンスデータを反映する
  fromJson(String resData) {
    Map<String,dynamic> _resDataMap =
              jsonDecode(resData);
    //入出力データ用
    if (_resDataMap["srchOrderForm"]==null) {
      sortItemName = "";
      sortOrder = "";
      updMode = "";
    } else {
      sortItemName = _resDataMap["srchOrderForm"]["sortItemName"] ?? "";
      sortOrder = _resDataMap["srchOrderForm"]["sortOrder"] ?? "";
      updMode = _resDataMap["srchOrderForm"]["updMode"] ?? "";
    }
    // プロパティ エラーメッセージ
    srchOrderErrForm.fromJson(resData);
  }

  /// HTTPレスポンスデータを作成する
  Map<String,dynamic> toJsonMap (String _mode, String _csrf, [int page=0]) {
    Map<String,dynamic> rtnMap = {
      'sortItemName': sortItemName,
      'sortOrder': sortOrder,
      'updMode': updMode,
    };
    return rtnMap;
  }

  /// 入出力データを、TextFormFieldに設定する
  forSrchOrderFormController(
      TextEditingController sortItemNameController,
      TextEditingController sortOrderController,
      TextEditingController updModeController,
      ) {
    sortItemNameController.text = sortItemName;
    sortOrderController.text = sortOrder;
    updModeController.text = updMode;
  }

  /// TextFormField値を、入出力データに設定する
  fromSrchOrderFormController(
      TextEditingController sortItemNameController,
      TextEditingController sortOrderController,
      TextEditingController updModeController,
      ) {
    sortItemName = sortItemNameController.text;
    sortOrder = sortOrderController.text;
    updMode = updModeController.text;
  }
}

■修正後のsrch_order_err_form.dart

import 'dart:convert';

/// ユーザー情報画面プロパティ エラーメッセージ用Form
class SrchOrderErrForm {
  //プロパティ エラーメッセージ用
  late List<String> sortItemNameErr;
  late List<String> sortOrderErr;
  late List<String> updModeErr;

  /// コンストラクタ
  // Dartでは「コンストラクタ名.任意名称」で複数のコンストラクタを定義する
  // 「クラス名(this.name,・・・);」コンストラクタはいらないので,
  // これだけにする。
  // 初期値のクラスを作成している
  SrchOrderErrForm.initData()  {
    //エラーメッセージ用
    sortItemNameErr = <String>[];
    sortOrderErr = <String>[];
    updModeErr = <String>[];
  }

  /// HTTPレスポンスデータを反映する
  fromJson(String resData) {
    Map<String,dynamic> _resDataMap =
              jsonDecode(resData);
    //エラーメッセージ用
    if (_resDataMap["resErrorData"]==null) {
      sortItemNameErr = <String>[];
      sortOrderErr = <String>[];
      updModeErr = <String>[];
    } else {
      sortItemNameErr = _resDataMap["resErrorData"]["srchOrderForm.sortItemName"]!=null?_resDataMap["resErrorData"]["srchOrderForm.sortItemName"].cast<String>():<String>[];
      sortOrderErr = _resDataMap["resErrorData"]["srchOrderForm.sortOrder"]!=null?_resDataMap["resErrorData"]["srchOrderForm.sortOrder"].cast<String>():<String>[];
      updModeErr = _resDataMap["resErrorData"]["srchOrderForm.updMode"]!=null?_resDataMap["resErrorData"]["srchOrderForm.updMode"].cast<String>():<String>[];
    }
  }
}

■修正後のsrch_order_form_in_msg_form.dart

import 'dart:convert';
import 'package:flutter_app/form/comm/message_form.dart';
import 'package:flutter_app/form/comm/srch_order_form.dart';

/// 共通・検索ソート順Form。(MessageFormクラスを包含している)
class SrchOrderFormInMsgForm {
  // 共通・検索ソート順Form
  late SrchOrderForm srchOrderForm; // 共通・検索ソート順Form
  // 共通・メッセージ
  late MessageForm messageForm; // 共通・メッセージ

  /// コンストラクタ
  // Dartでは「コンストラクタ名.任意名称」で複数のコンストラクタを定義する
  // 「クラス名(this.sortItemName,・・・);」コンストラクタはいらないので,
  // これだけにする。
  // 初期値のクラスを作成している
  SrchOrderFormInMsgForm.initData()  {
    // 共通・検索ソート順Form
    srchOrderForm = SrchOrderForm.initData();
    // 共通・メッセージ
    messageForm = MessageForm.initData();
  }

  /// HTTPレスポンスデータを反映する
  fromJson(String resData) {
    // 共通・検索ソート順Form
    srchOrderForm.fromJson(resData);
    // 共通・メッセージ
    messageForm.fromJson(resData);
  }

  /// HTTPレスポンスデータを作成する
  Map<String,dynamic> toJsonMap (String _mode, String _csrf, [int page=0]) {
    Map<String,dynamic> rtnMap = {
      'srchOrderForm': srchOrderForm.toJsonMap(_mode, _csrf, page),
      'formComm': messageForm.toJsonMap(_mode, _csrf, page),
    };
    return rtnMap;
  }

  /// http.postのbodyで使用するJsonデータを返却する
  String toJson(String _mode, String _csrf, [int page=1]) {
    return json.encode(toJsonMap(_mode, _csrf, page));
  }
}

③バックエンドSpring側
■修正後のUserCommController.java(ユーザー情報管理の共通コントローラー)

package com.kaz02u.demo.controller.adminComm;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import com.kaz02u.demo.entity.User;
import com.kaz02u.demo.fForm.FormComm;
import com.kaz02u.demo.fForm.SrchOrderFForm;
import com.kaz02u.demo.fForm.UserFForm;
import com.kaz02u.demo.fForm.UserSrchFForm;
import com.kaz02u.demo.form.SessionUserSrchForm;
import com.kaz02u.demo.form.SessionUserSrchOrderForm;
import com.kaz02u.demo.form.SrchOrderForm;
import com.kaz02u.demo.form.UserForm;
import com.kaz02u.demo.form.UserSrchForm;
import com.kaz02u.demo.response.ResData;
import com.kaz02u.demo.service.UserService;
import com.kaz02u.demo.utils.AppProperties;
import com.kaz02u.demo.utils.Functions;
import com.kaz02u.demo.utils.PageNavi;

import lombok.extern.slf4j.Slf4j;

/**
 * ユーザー情報管理の共通コントローラー
 *
 */
@Controller
//log出力用
@Slf4j
public class UserCommController {

	/**
	 * 一覧表示時の、ソート項目の項目名(Entityの項目名。テーブル項目名ではない)
	 */
	protected static String[] sortItemNames = {"id", "name", "email", "roles", "enableFlag"};
	
	/**
	 * PageableDefaultのsize(1画面中の表示レコード数)を指定
	 */
	public static final int pageableDefaultSize = 10;

	@Autowired
	protected AppProperties appProperties;
	@Autowired
	protected UserService userService;
	@Autowired
	protected SessionUserSrchForm sessionUserSrchForm;
	@Autowired
	protected SessionUserSrchOrderForm sessionUserSrchOrderForm;
    @Autowired
	protected MessageSource messageSource;
 
	//=======================================================
	// ユーザー情報一覧登録
	//=======================================================
	//=======================================================
	// ユーザー情報登録
	//=======================================================
	
	/**
	 * リターン共通処理(Flutter、PC・WEB共用)
	 * リターン共通処理
	 *
	 * @param url 遷移先
	 * @param model モデル
	 * @param result チェック結果
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @param resFormName レスポンスForm名
	 * @param page 検索以外の時のページ
	 * @return Flutter用String:jsonデータ PC・WEB用 Map<String, Object>:遷移先
	 */
	protected Object returnComm(String url ,Model model,BindingResult result, boolean flutterFlg, FormComm formComm, String resFormName, String srchFormName, String srchOrdeFormName) {
		if (flutterFlg) {
			ResData resData = new ResData(model, result);
	        return resData.getResDataMap(messageSource, formComm, resFormName, srchFormName, srchOrdeFormName);
		} else {
			return url;
		}
	}

	/**
	 * userInsSubメソッド(Flutter、PC・WEB共用)
	 * ユーザー情報登録を表示する処理のサブモジュール
	 * 
	 * @param model モード
	 */
	protected void userInsSub(Model model) {
		UserForm userForm = new UserForm();
		model.addAttribute("userForm", userForm);
		model.addAttribute("mode", "ins");
	}
	
	/**
	 * ユーザー情報登録共通処理(Flutter、PC・WEB共用)
	 * ユーザー情報登録する共通処理
	 *
	 * @param userForm ユーザー情報登録
	 * @param result チェック結果
	 * @param model モデル
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @return Flutter用:jsonデータ PC・WEB用:遷移先
	 */
	protected Object userInsDoComm(UserForm userForm, BindingResult result, Model model, boolean flutterFlg) {
		if (flutterFlg) {
			model.addAttribute("userForm", userForm);
		}
		//エラーになったときのモードを設定
		model.addAttribute("mode", "ins");
		if (result.hasErrors()) {
			model.addAttribute("errorMessage", "エラーが発生しました");
			model.addAttribute("itemErrorMessages", result.toString());
			return returnComm("/members/admin/user/userRegister", model, result, flutterFlg, null, "userForm", null, null);
		}
	    
		try {
			//ロールを文字列にする
			String[] roles = userForm.getRolesArray();	
			userService.register(userForm.getName(), userForm.getEmail(), userForm.getPassword(), roles, userForm.getEnableFlag());
		} catch(Exception e){
			if (e.getMessage() != null && e.getMessage().equals("invalid email")) {
				result.rejectValue("email", "validation.already-registered", new String[] {"『メールアドレス』"}, "");
				model.addAttribute("itemErrorMessages", result.toString());
			} else {
	            e.printStackTrace();
	            log.error("エラーが発生しました", e);
				model.addAttribute("errorMessage", "エラーが発生しました");
			}
			return returnComm("/members/admin/user/userRegister", model, result, flutterFlg, null, "userForm", null, null);
		}
		userInsSub(model);
		model.addAttribute("successMessage", "ユーザー情報登録が完了しました");
		return returnComm("/members/admin/user/userRegister", model, result, flutterFlg, null, "userForm", null, null);
	}
	  

	/**
	 * ユーザー情報登録共通処理(Flutter、PC・WEB共用)
	 * ユーザー情報登録する共通処理
	 *
	 * @param userFForm Flutter向けユーザー情報+ページ番号
	 * @param id ユーザー情報ID
	 * @param page page
	 * @param model モデル
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @return Flutter用:jsonデータ PC・WEB用:遷移先
	 */
	protected Object userUpdComm(UserFForm userFForm, String id, String page, Model model, boolean flutterFlg) {
		model.addAttribute("mode", "upd");
		model.addAttribute("page", page);
		UserForm userForm = new UserForm();
		try {
			//ユーザー情報を取得する
			userForm= userService.findByPkForUserForm(Long.valueOf(id));
		} catch(Exception e){
			if (e.getMessage() != null && e.getMessage().equals("invalid pk")) {
				model.addAttribute("successMessage", "『id』=" + userForm.getId() +"は既に削除されています");
			} else {
		        e.printStackTrace();
		        log.error("エラーが発生しました", e);
				model.addAttribute("errorMessage", "エラーが発生しました");
			}
			Pageable pageable = PageRequest.of(Integer.parseInt(page), pageableDefaultSize);
			userListBackSub(model, pageable);
			FormComm formComm = new FormComm();
			if (flutterFlg) {
				formComm = userListBackSubForFlutter(userFForm.getFormComm().get_csrf(), model);
			}
			return returnComm("/members/admin/user/userList", model, null, flutterFlg, formComm, null,"userSrchForm", "srchOrderForm");
		}
		model.addAttribute("userForm", userForm);
		return returnComm("/members/admin/user/userAmend", model, null, flutterFlg, flutterFlg?userFForm.getFormComm():null, "userForm", null, null);
	}

	/**
	 * ユーザー情報登録共通処理(Flutter、PC・WEB共用)
	 * ユーザー情報登録する共通処理
	 *
	 * @param userFForm Flutter向けユーザー情報+ページ番号
	 * @param userForm ユーザー情報登録
	 * @param result チェック結果
	 * @param page page
	 * @param model モデル
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @return Flutter用:jsonデータ PC・WEB用:遷移先
	 */
	protected Object userUpdDoComm(UserFForm userFForm, UserForm userForm, BindingResult result, String page, Model model, boolean flutterFlg) {
		//エラーになったときのモードを設定
		model.addAttribute("mode", "upd");
		model.addAttribute("page", page);
		if (flutterFlg) {
			model.addAttribute("userForm", userFForm.getUserForm());
		}
		if (result.hasErrors()) {
			model.addAttribute("itemErrorMessages", result.toString());
			return returnComm("/members/admin/user/userAmend", model, result, flutterFlg, flutterFlg?userFForm.getFormComm():null, "userForm", null, null);
		}
	    
		try {
			//ロールを文字列にする
			String[] roles = userForm.getRolesArray();
			userService.update(userForm.getId(), userForm.getName(), userForm.getEmail(), userForm.getPassword(), roles, userForm.getEnableFlag());
		} catch(Exception e){
			if (e.getMessage() != null && e.getMessage().equals("invalid pk")) {
				result.rejectValue("id", "validation.already-deleted", new String[] {"『id』"}, "");
			} else if (e.getMessage() != null && e.getMessage().equals("invalid email")) {
				result.rejectValue("email", "validation.already-registered", new String[] {"『メールアドレス』"}, "");
			} else {
	            e.printStackTrace();
	            log.error("エラーが発生しました", e);
				model.addAttribute("errorMessage", "エラーが発生しました");
			}
			return returnComm("/members/admin/user/userAmend", model, result, flutterFlg, flutterFlg?userFForm.getFormComm():null, "userForm", null, null);
		}
		  
		Pageable pageable = PageRequest.of(Integer.parseInt(page), pageableDefaultSize);
		model.addAttribute("successMessage", "ユーザー情報更新(" + "『id』=" + userForm.getId() + ")が完了しました");
		userListBackSub(model, pageable);
		FormComm formComm = new FormComm();
		if (flutterFlg) {
			formComm = userListBackSubForFlutter(userFForm.getFormComm().get_csrf(), model);

		}
		return returnComm("/members/admin/user/userList", model, result, flutterFlg, formComm, null,"userSrchForm", "srchOrderForm");
	}

	
	//=======================================================
	// ユーザー情報詳細表示
	//=======================================================

	/**
	 * ユーザー情報詳細表示処理(Flutter、PC・WEB共用)
	 * ユーザー情報詳細を表示する共通処理
	 *
	 * @param userFForm Flutter向けユーザー情報+ページ番号
	 * @param id ユーザー情報ID
	 * @param page page
	 * @param model モデル
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @return Flutter用:jsonデータ PC・WEB用:遷移先
	 */
	protected Object userDetailComm(UserFForm userFForm, String id, String page, Model model, boolean flutterFlg) {
		model.addAttribute("page", page);
		User user = null;
		try {
			//ユーザー情報を取得する
			user = userService.findByPk(Long.parseLong(id));
			if (user == null) {
	            log.error("user not found:pk={}", id);
				throw new RuntimeException("invalid pk");
			}
		} catch(Exception e){
			if (e.getMessage() != null && e.getMessage().equals("invalid pk")) {
	    		model.addAttribute("successMessage", "『id』=" + id +"は既に削除されています");
			} else {
	            e.printStackTrace();
	            log.error("エラーが発生しました", e);
	    		model.addAttribute("errorMessage", "エラーが発生しました");
			}
			Pageable pageable = PageRequest.of(Integer.parseInt(page), pageableDefaultSize);
			userListBackSub(model, pageable);
			FormComm formComm = new FormComm();
			if (flutterFlg) {
				formComm =userListBackSubForFlutter(userFForm.getFormComm().get_csrf(), model);
			}
			return returnComm("/members/admin/user/userList", model, null, flutterFlg, formComm, null,"userSrchForm", "srchOrderForm");
		}
		if (flutterFlg) {
			//同一プロパティ(型名まで同じもの)コピー
			BeanUtils.copyProperties(user, userFForm.getUserForm());
			model.addAttribute("userForm", userFForm.getUserForm());
			model.addAttribute("mode", "detail");
		} else {
			model.addAttribute("user", user);
		}
		return returnComm("/members/admin/user/userDetail", model, null, flutterFlg, flutterFlg?userFForm.getFormComm():null, "userForm", null, null);
	}
	  
	//=======================================================
	// ユーザー情報リスト及び、一覧更新、一覧削除
	//=======================================================
	/**
	 * ユーザー情報リスト検索条件表示処理(Flutter、PC・WEB共用)
	 * ユーザー情報リスト検索条件を表示する処理
	 *
	 * @param userSrchFForm Flutter向けユーザー情報リスト検索条件+ソート条件+ページ番号
	 * @param userSrchForm ユーザー情報リスト検索条件
	 * @param srchOrderForm ユーザー情報リスト昇順降順条件
	 * @param model モデル
	 * @param pageable ページ
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @return Flutter用:jsonデータ PC・WEB用:遷移先
	 */
	@SuppressWarnings("rawtypes")
	protected Object userListComm(UserSrchFForm userSrchFForm,UserSrchForm userSrchForm, SrchOrderForm srchOrderForm, Model model, Pageable pageable, boolean flutterFlg) {
		//セッションに載せる
		this.sessionUserSrchForm.setUserSrchForm(userSrchForm);
		this.sessionUserSrchOrderForm.setSrchOrderForm(srchOrderForm);
		srchOrderForm.setSortItemName(sortItemNames[0]);
		srchOrderForm.setSortOrder("A");
		userListSub(userSrchForm, srchOrderForm, model, pageable);
		if (flutterFlg) {
			Map<String, Object> modelMap = model.asMap();
			userSrchFForm.getFormComm().setPage(((Page)modelMap.get("page")).getNumber() + 1);
			// Flutter向け検索条件+ソート条件+ページ番号
			model.addAttribute("userSrchFForm", userSrchFForm);
		}
		model.addAttribute("userSrchForm", userSrchForm);
		model.addAttribute("srchOrderForm", srchOrderForm);

		return returnComm("/members/admin/user/userList", model, null, flutterFlg, flutterFlg?userSrchFForm.getFormComm():null, null,"userSrchForm", "srchOrderForm");
	}

	/**
	 * ユーザー情報リスト一覧表示処理(Flutter、PC・WEB共用)
	 * 検索ボタン押下により、ユーザー情報リスト一覧を表示する処理
	 * 
	 * @param userSrchFForm Flutter向けユーザー情報リスト検索条件+ソート条件+ページ番号
	 * @param userSrchForm ユーザー情報リスト検索条件
	 * @param result チェック結果
	 * @param model モデル
	 * @param pageable ページ
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @return Flutter用:jsonデータ PC・WEB用:遷移先
	 */
	@SuppressWarnings("rawtypes")
	protected Object userListDoComm(UserSrchFForm userSrchFForm, UserSrchForm userSrchForm, BindingResult result, Model model, Pageable pageable, boolean flutterFlg) {
		if (flutterFlg) {
			// Flutter向け検索条件+ソート条件+ページ番号
			model.addAttribute("userSrchFForm", userSrchFForm);
		}
		model.addAttribute("userSrchForm", userSrchForm);

		if (result.hasErrors()) {
			model.addAttribute("itemErrorMessages", result.toString());
			return returnComm("/members/admin/user/userList", model, result, flutterFlg, flutterFlg?userSrchFForm.getFormComm():null, null,"userSrchForm", "srchOrderForm");
		} else {
			//セッションに載せる
			this.sessionUserSrchForm.setUserSrchForm(userSrchForm);
			this.sessionUserSrchOrderForm.getSrchOrderForm().setSortItemName(sortItemNames[0]);
			this.sessionUserSrchOrderForm.getSrchOrderForm().setSortOrder("A");
		}
		userListSub(this.sessionUserSrchForm.getUserSrchForm(), this.sessionUserSrchOrderForm.getSrchOrderForm(), model, pageable);
		model.addAttribute("srchOrderForm", this.sessionUserSrchOrderForm.getSrchOrderForm());
		if (flutterFlg) {
			Map<String, Object> modelMap = model.asMap();
			userSrchFForm.getFormComm().setPage(((Page)modelMap.get("page")).getNumber() + 1);
		}
		return returnComm("/members/admin/user/userList", model, result, flutterFlg, flutterFlg?userSrchFForm.getFormComm():null, null,"userSrchForm", "srchOrderForm");
	}
  
	/**
	 * ユーザー情報リスト一覧表示処理(Flutter、PC・WEB共用)
	 * ページリンク押下により、ユーザー情報リスト一覧を表示する処理
	 *
	 * @param srchOrderFForm Flutter向けユーザー情報ソート条件+ページ番号
	 * @param model モデル
	 * @param pageable ページ
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @return Flutter用:jsonデータ PC・WEB用:遷移先
	 */
	protected Object  userListBackComm(SrchOrderFForm srchOrderFForm, Model model, Pageable pageable, boolean flutterFlg) {
		userListBackSub(model, pageable);
		FormComm formComm = new FormComm();
		if (flutterFlg) {
			formComm = userListBackSubForFlutter(srchOrderFForm.getFormComm().get_csrf(), model);
		}
		return returnComm("/members/admin/user/userList", model, null, flutterFlg, formComm, null,"userSrchForm", "srchOrderForm");
	}


	/**
	 * userListBackSubForFlutterメソッド(Flutter用)
	 * ユーザー情報リスト一覧表示サブ処理Flutter用差分
	 * 
	 * @param csrf csrf
	 * @param model モデル
	 * @return FormComm
	 */
	@SuppressWarnings("rawtypes")
	private FormComm userListBackSubForFlutter(String csrf, Model model) {
		FormComm formComm = new FormComm();
		formComm.set_csrf(csrf);
		Map<String, Object> modelMap = model.asMap();
		formComm.setPage(((Page)modelMap.get("page")).getNumber() + 1);
		model.addAttribute("mode", "list_back");
		return formComm;
	}

	/**
	 * userListBackSubメソッド(Flutter、PC・WEB共用)
	 * ユーザー情報リスト一覧表示サブ処理
	 * 
	 * @param model モデル
	 * @param pageable ページ
	 */
	protected void userListBackSub(Model model, Pageable pageable) {
		userListSub(this.sessionUserSrchForm.getUserSrchForm(), this.sessionUserSrchOrderForm.getSrchOrderForm(), model, pageable);
		model.addAttribute("userSrchForm", this.sessionUserSrchForm.getUserSrchForm());
		model.addAttribute("srchOrderForm", this.sessionUserSrchOrderForm.getSrchOrderForm());
	}
	  
	/**
	 * ユーザー情報リスト一覧表示処理(Flutter、PC・WEB共用)
	 * ページリンク押下により、ユーザー情報リスト一覧を表示する処理
	 *
	 * @param srchOrderFForm Flutterユーザー情報リスト昇順降順条件
	 * @param srchOrderForm ユーザー情報リスト昇順降順条件
	 * @param id ID
	 * @param model モデル
	 * @param pageable ページ
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @return Flutter用:jsonデータ PC・WEB用:遷移先
	 */
	@SuppressWarnings("rawtypes")
	protected Object userListUpDwnComm(SrchOrderFForm srchOrderFForm, SrchOrderForm srchOrderForm, BindingResult result, Model model, Pageable pageable, boolean flutterFlg) {
		if (result.hasErrors()) {
			model.addAttribute("itemErrorMessages", result.toString());
			return returnComm("/members/admin/user/userList", model, result, flutterFlg, flutterFlg?srchOrderFForm.getFormComm():null, null,"userSrchForm", "srchOrderForm");
		} else {
			//セッションに載せる
			this.sessionUserSrchOrderForm.setSrchOrderForm(srchOrderForm);
			if (this.sessionUserSrchOrderForm.getSrchOrderForm().getSortItemName().equals(srchOrderForm.getSortItemName())) {
				if (srchOrderForm.getSortOrder().equals("A")) {
					srchOrderForm.setSortOrder("D");
				} else {
					srchOrderForm.setSortOrder("A");
				}
			} else {
				srchOrderForm.setSortOrder("A");
			}
			model.addAttribute("srchOrderForm", srchOrderForm);
		}
		userListSub(this.sessionUserSrchForm.getUserSrchForm(), this.sessionUserSrchOrderForm.getSrchOrderForm(), model, pageable);
		FormComm formComm = new FormComm();
		if (flutterFlg) {
			Map<String, Object> modelMap = model.asMap();
			formComm.setPage(((Page)modelMap.get("page")).getNumber() +1);
		}
		model.addAttribute("userSrchForm", this.sessionUserSrchForm.getUserSrchForm());

		return returnComm("/members/admin/user/userList", model, result, flutterFlg, formComm, null,"userSrchForm", "srchOrderForm");
	}

	/**
	 * userListSubメソッド(Flutter、PC・WEB共用)
	 * 検索条件で検索するサブ
	 * 
	 * @param userSrchForm ユーザー情報リスト検索条件
	 * @param srchOrderForm ユーザー情報リスト昇順降順条件
	 * @param mode モード
	 * @param pageable ページ
	 */
	protected void userListSub(UserSrchForm userSrchForm, SrchOrderForm srchOrderForm, Model model, Pageable pageable) {
		//SortItemNameとSortOrderの内容をチェック、編集する
		Functions.editSortItemNameOrder(srchOrderForm, sortItemNames);
		//検索SQL作成
		String countSql = editSql("count");
		String selectSql = editSql("select");
		List<Object> argsList = getArgsList(userSrchForm);
		Page<User> usersPage = userService.getFindsUser(countSql, selectSql, argsList, pageable);
		model.addAttribute("page", usersPage);
		model.addAttribute("users", usersPage.getContent());

		String strPaging = PageNavi.getHTML(5, usersPage, "/members/admin/user/userA");
		log.debug("pageable.getPageSize()=" + pageable.getPageSize());
		log.debug("usersPage.getTotalPages()=" + usersPage.getTotalPages());
		log.debug("usersPage.getNumber()=" + (usersPage.getNumber()+1));
		log.debug("strPaging=" + strPaging);
		model.addAttribute("strPaging", strPaging);
	}

	/**
	 * editSqlメソッド
	 * SQL文を編集する
	 * 
	 * @param kbn count:件数SQL、select:検索SQL
	 * @return SQL文
	 */
	protected String editSql(String kbn) {
		int i = 0;
		String sql = "from User u ";
		String where = 
				(ObjectUtils.isEmpty(this.sessionUserSrchForm.getUserSrchForm().getName())?"":((i==0?"":" and") + " u.name like :p" + ++i)) +
				(ObjectUtils.isEmpty(this.sessionUserSrchForm.getUserSrchForm().getEmail())?"":((i==0?"":" and") + " u.email = :p" + ++i)) +
				(ObjectUtils.isEmpty(this.sessionUserSrchForm.getUserSrchForm().getRoles())?"":((i==0?"":" and") + " u.roles like :p" + ++i)) +
				(ObjectUtils.isEmpty(this.sessionUserSrchForm.getUserSrchForm().getEnableFlag())?"":((i==0?"":" and") + " u.enableFlag=:p" + ++i));
		//条件があるとき
		if (i != 0) {
			sql = sql + "where " + where;
		}
		if (kbn.equals("count")) {
			 sql =  "select count(u) " + sql;
		} else {
			 sql =  "select u " + sql + " order by u." + 
						this.sessionUserSrchOrderForm.getSrchOrderForm().getSortItemName() + " "  + 
						(this.sessionUserSrchOrderForm.getSrchOrderForm().getSortOrder().equals("A")?"ASC":"DESC");;
		}
		return sql;
	}

	/**
	 * getArgsListメソッド
	 * SQL文用変数
	 * 
	 * @param userSrchForm
	 * @return SQL文用変数リスト(型は、String、Long、Booleanなどあるので、Objectにしている)
	 */
	protected List<Object> getArgsList(UserSrchForm userSrchForm) {
		List<Object> argsList = new ArrayList<Object>();
		if (!ObjectUtils.isEmpty(userSrchForm.getName())) {
			argsList.add(userSrchForm.getName() + "%");
		}
		if (!ObjectUtils.isEmpty(userSrchForm.getEmail())) {
			argsList.add(userSrchForm.getEmail());
		}
		if (!ObjectUtils.isEmpty(userSrchForm.getRoles())) {
			argsList.add("%" + userSrchForm.getRoles() + "%");
		}
		if (!ObjectUtils.isEmpty(userSrchForm.getEnableFlag())) {
			argsList.add(Boolean.valueOf(userSrchForm.getEnableFlag()));
		}
		return argsList;
	}

	/**
	 * ユーザー情報削除処理(Flutter、PC・WEB共用)
	 *
	 * @param userFForm Flutter向けユーザー情報+ページ番号
	 * @param id ID
	 * @param model モデル
	 * @param pageable ページ
	 * @param flutterFlg true:Flutter用 false:PC・WEB用
	 * @return Flutter用:jsonデータ PC・WEB用:遷移先
	 */
	protected Object userDelDoComm(UserFForm userFForm, Long id, Model model, Pageable pageable, boolean flutterFlg) {
		log.info("delete form user:{}", id);
		try {
			userService.delete(id);
		} catch(Exception e){
			if (e.getMessage() != null && e.getMessage().equals("invalid pk")) {
	    		model.addAttribute("successMessage", "『id』=" + id +"は既に削除されています");
			} else {
	            e.printStackTrace();
	            log.error("エラーが発生しました", e);
	    		model.addAttribute("errorMessage", "エラーが発生しました");
			}
			userListBackSub(model, pageable);
			FormComm formComm = new FormComm();
			if (flutterFlg) {
				formComm = userListBackSubForFlutter(userFForm.getFormComm().get_csrf(), model);
			}
			return returnComm("/members/admin/user/userList", model, null, flutterFlg, formComm, null,"userSrchForm", "srchOrderForm");
	    }
		userListBackSub(model, pageable);
		model.addAttribute("successMessage", "ユーザー情報削除(" + "『id』=" + id + ")が完了しました");
		FormComm formComm = new FormComm();
		if (flutterFlg) {
			formComm = userListBackSubForFlutter(userFForm.getFormComm().get_csrf(), model);
		}
		return returnComm("/members/admin/user/userList", model, null, flutterFlg, formComm, null,"userSrchForm", "srchOrderForm");
	}

}

■修正後のUserFlutterController.java(Flutter用ユーザー情報管理のコントローラー)

package com.kaz02u.demo.controller.adminFlutter;
import java.util.Map;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import com.kaz02u.demo.controller.adminComm.UserCommController;
import com.kaz02u.demo.fForm.SrchOrderFForm;
import com.kaz02u.demo.fForm.UserFForm;
import com.kaz02u.demo.fForm.UserSrchFForm;
import com.kaz02u.demo.validation.GroupOrder;
import lombok.extern.slf4j.Slf4j;

/**
 * Flutter用ユーザー情報管理のコントローラー
 *
 */
@Controller
//log出力用
@Slf4j
public class UserFlutterController extends UserCommController {
	//=======================================================
	// ユーザー情報一覧登録
	//=======================================================
	//=======================================================
	// ユーザー情報登録
	//=======================================================

	/**
	 * ユーザー情報登録表示処理(Flutter用)
	 * ユーザー情報登録を表示する処理
	 *
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/ins")
	@ResponseBody
	public Map<String, Object> userInsFlutter(Model model) {
		userInsSub(model);
		return (Map<String, Object>)returnComm("/members/admin/user/userRegister", model, null, true, null, "userForm", null, null);
 	}
	  
	/**
	 * ユーザー情報登録処理(Flutter用)
	 * ユーザー情報登録する処理
	 *
	 * @param userFForm Flutter向けユーザー情報+ページ番号
	 * @param result チェック結果
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/ins_do")
	@ResponseBody
	public Map<String, Object> userInsDoFlutter(@RequestBody @Validated(GroupOrder.class)  UserFForm userFForm,
			BindingResult result,
			Model model) {
		return (Map<String, Object>)userInsDoComm(userFForm.getUserForm(), result, model, true);
	}
	
	//=======================================================
	// ユーザー情報更新
	//=======================================================
	/**
	 * ユーザー情報更新表示処理(Flutter用)
	 * ユーザー情報更新を表示する処理
	 *
	 * @param userFForm Flutter向けユーザー情報+ページ番号
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/upd")
	@ResponseBody	
	public Map<String, Object>  userUpdFlutter(@RequestBody UserFForm userFForm,
			Model model) {
		String id = userFForm.getUserForm().getId().toString();
		return (Map<String, Object>)userUpdComm(userFForm, id, userFForm.getFormComm().getPage().toString(), model, true);
	}
	  
	/**
	 * ユーザー情報更新処理(Flutter用)
	 * ユーザー情報更新する処理
	 *
	 * @param userFForm Flutter向けユーザー情報+ページ番号
	 * @param result チェック結果
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/upd_do")
	@ResponseBody	
	public  Map<String, Object> userUpdDoFlutter(@RequestBody @Validated(GroupOrder.class) UserFForm userFForm,
			BindingResult result,
			Model model) {
		return ( Map<String, Object>)userUpdDoComm(userFForm, userFForm.getUserForm(), result, Integer.toString(userFForm.getFormComm().getPage()-1), model, true);
	}

	//=======================================================
	// ユーザー情報詳細表示
	//=======================================================
	/**
	 * ユーザー情報詳細表示処理(Flutter用)
	 * ユーザー情報詳細を表示する処理
	 *
	 * @param userFForm Flutter向けユーザー情報+ページ番号
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/detail")
	@ResponseBody	
	public  Map<String, Object> userDetailFlutter(@RequestBody UserFForm userFForm,
			Model model) {
		return ( Map<String, Object>)userDetailComm(userFForm, Long.toString(userFForm.getUserForm().getId()), Integer.toString(userFForm.getFormComm().getPage()-1), model, true);
	}

	//=======================================================
	// ユーザー情報リスト及び、一覧更新、一覧削除
	//=======================================================
	/**
	 * ユーザー情報リスト検索条件表示処理(Flutter用)
	 * ユーザー情報リスト検索条件を表示する処理
	 *
	 * @param userSrchFForm Flutter向けユーザー情報リスト検索条件+ソート条件+ページ番号
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/list")
	@ResponseBody
	public Map<String, Object> userListFlutter(@RequestBody UserSrchFForm userSrchFForm,
			Model model) {
		int page = ObjectUtils.isEmpty(userSrchFForm.getFormComm().getPage())||userSrchFForm.getFormComm().getPage()==0?0:userSrchFForm.getFormComm().getPage()-1;
	    Pageable pageable = PageRequest.of(page, pageableDefaultSize, Sort.unsorted());
		return (Map<String, Object>)userListComm(userSrchFForm, userSrchFForm.getUserSrchForm(), userSrchFForm.getSrchOrderForm(), model,pageable, true);
	}
  
	/**
	 * ユーザー情報リスト一覧表示処理(Flutter用)
	 * 検索ボタン押下により、ユーザー情報リスト一覧を表示する処理
	 * 
	 * @param userSrchFForm Flutter向けユーザー情報リスト検索条件+ソート条件+ページ番号
	 * @param result チェック結果
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/list_do")
	@ResponseBody
	public Map<String, Object> userListDo(@RequestBody @Validated(GroupOrder.class) UserSrchFForm userSrchFForm,
			BindingResult result,
			Model model) {
		int page = ObjectUtils.isEmpty(userSrchFForm.getFormComm().getPage())||userSrchFForm.getFormComm().getPage()==0?0:userSrchFForm.getFormComm().getPage()-1;
	    Pageable pageable = PageRequest.of(page, pageableDefaultSize, Sort.unsorted());
		return (Map<String, Object>)userListDoComm(userSrchFForm, userSrchFForm.getUserSrchForm(), result, model, pageable, true);
	}

	/**
	 * ユーザー情報リスト一覧表示処理(Flutter用)
	 * ページリンク押下により、ユーザー情報リスト一覧を表示する処理
	 * 
	 * @param srchOrderFForm Flutter向けユーザー情報ソート条件+ページ番号
	 * @param model モデル
	 * @return jsonデータ 
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/list_back")
	@ResponseBody
	public Map<String, Object> userListBack(@RequestBody SrchOrderFForm srchOrderFForm,
			Model model) {
		int page = ObjectUtils.isEmpty(srchOrderFForm.getFormComm().getPage())||srchOrderFForm.getFormComm().getPage()==0?0:srchOrderFForm.getFormComm().getPage()-1;
	    Pageable pageable = PageRequest.of(page, pageableDefaultSize, Sort.unsorted());
		return (Map<String, Object>)userListBackComm(srchOrderFForm, model, pageable, true);
	}
	
	/**
	 * ユーザー情報リスト一覧表示処理(Flutter用)
	 * 並び順選択により、ユーザー情報リスト一覧を表示する処理
	 * 
	 * @param srchOrderFForm Flutter向けユーザー情報リスト昇順降順条件+ページ番号
	 * @param result チェック結果
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/list_up_dwn")
	@ResponseBody
	public Map<String, Object> userListUpDwn(@RequestBody @Validated SrchOrderFForm srchOrderFForm,
			BindingResult result,
			Model model) {
		int page = ObjectUtils.isEmpty(srchOrderFForm.getFormComm().getPage())||srchOrderFForm.getFormComm().getPage()==0?0:srchOrderFForm.getFormComm().getPage()-1;
	    Pageable pageable = PageRequest.of(page, pageableDefaultSize, Sort.unsorted());
		return (Map<String, Object>)userListUpDwnComm(srchOrderFForm, srchOrderFForm.getSrchOrderForm(), result, model, pageable, true);
	}

	/**
	 * ユーザー情報削除処理(Flutter用)
	 * 
	 * @param userFForm Flutter向けユーザー情報+ページ番号
	 * @param model モデル
	 * @return jsonデータ
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("/members/admin/user/userA/del_do")
	@ResponseBody
	public Map<String, Object> userDelDo(@RequestBody UserFForm userFForm,
			Model model) {
		int page = ObjectUtils.isEmpty(userFForm.getFormComm().getPage())||userFForm.getFormComm().getPage()==0?0:userFForm.getFormComm().getPage()-1;
	    Pageable pageable = PageRequest.of(page, pageableDefaultSize, Sort.unsorted());
		return (Map<String, Object>)userDelDoComm(userFForm, userFForm.getUserForm().getId(), model, pageable, true);
	}

}

■修正後のUserPcController.java(Pc用ユーザー情報管理のコントローラー)

package com.kaz02u.demo.controller.adminPc;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.MimeTypeUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
import com.fasterxml.jackson.dataformat.csv.CsvGenerator.Feature;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvMappingException;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import com.kaz02u.demo.controller.adminComm.UserCommController;
import com.kaz02u.demo.csv.UserCsv;
import com.kaz02u.demo.entity.User;
import com.kaz02u.demo.exception.UploadComplexValidException;
import com.kaz02u.demo.form.SrchOrderForm;
import com.kaz02u.demo.form.UserForm;
import com.kaz02u.demo.form.UserSrchForm;
import com.kaz02u.demo.upload.UserUpload;
import com.kaz02u.demo.utils.CsvUtils;
import com.kaz02u.demo.utils.Functions;
import com.kaz02u.demo.validation.GroupOrder;

import lombok.extern.slf4j.Slf4j;

/**
 * Pc用ユーザー情報管理のコントローラー
 *
 */
@Controller
//リクエストマッピングURL指定
@RequestMapping(value = "/members/admin/user/userA")
//log出力用
@Slf4j
public class UserPcController extends UserCommController {
  
	//=======================================================
	// ユーザー情報一覧登録
	//=======================================================
	//=======================================================
	// ユーザー情報登録
	//=======================================================
	/**
	 * ユーザー情報登録表示処理 (PC・WEB用)
	 * ユーザー情報登録を表示する処理
	 *
	 * @param mode モード
	 * @param model モデル
	 * @return 遷移先
	 */
	@PostMapping(params="mode=ins")
	public String userIns(@RequestParam("mode") String mode,
			Model model) {
		userInsSub(model);
		return (String)returnComm("/members/admin/user/userRegister", model, null, false, null, null, null, null);
	}

	/**
	 * ユーザー情報登録処理(PC・WEB用)
	 * ユーザー情報登録する処理
	 *
	 * @param userForm ユーザー情報登録
	 * @param result チェック結果
	 * @param mode モード
	 * @param model モデル
 	 * @return 遷移先
	 */
	@PostMapping(params="mode=ins_do")
	public String userInsDo(@Validated(GroupOrder.class)  UserForm userForm,
			BindingResult result,
			@RequestParam("mode") String mode,
			Model model) {
		return (String)userInsDoComm(userForm, result, model, false);
	}

	//=======================================================
	// ユーザー情報詳細表示
	//=======================================================
	/**
	 * ユーザー情報詳細表示処理(PC・WEB用)
	 * ユーザー情報詳細を表示する処理
	 *
	 * @param id ID
	 * @param mode モード
	 * @param page page
	 * @param model モデル
	 * @return 遷移先
	 */
	@PostMapping(params="mode=detail")
	public String userDetail(
			@RequestParam("id") String id,
			@RequestParam("mode") String mode,
			@RequestParam("page") String page,
			Model model) {
		return (String)userDetailComm(null, id, page, model, false);
	}

	//=======================================================
	// ユーザー情報更新
	//=======================================================
	/**
	 * ユーザー情報更新表示処理(PC・WEB用)
	 * ユーザー情報更新を表示する処理
	 *
	 * @param id ユーザー情報ID
	 * @param mode モード
	 * @param page page
	 * @param model モデル
	 * @return 遷移先
	 */
	@PostMapping(params="mode=upd")
	public String userUpd(
			@RequestParam("id") String id,
			@RequestParam("mode") String mode,
			@RequestParam("page") String page,
			Model model) {
		return (String)userUpdComm(null, id, page, model, false);
	}
	  
	/**
	 * ユーザー情報更新処理(PC・WEB用)
	 * ユーザー情報更新する処理
	 *
	 * @param userForm ユーザー情報登録
	 * @param result チェック結果
	 * @param mode モード
	 * @param page page
	 * @param model モデル
	 * @return 遷移先
	 */
	@PostMapping(params="mode=upd_do")
	public String userUpdDo(@Validated(GroupOrder.class)  UserForm userForm,
			BindingResult result,
			@RequestParam("mode") String mode,
			@RequestParam("page") String page,
			Model model) {
		return (String)userUpdDoComm(null, userForm, result, page, model, false);
	}
 
	//=======================================================
	// ユーザー情報リスト及び、一覧更新、一覧削除
	//=======================================================
	/**
	 * ユーザー情報リスト検索条件表示処理(PC・WEB用)
	 * ユーザー情報リスト検索条件を表示する処理
	 *
	 * @param userSrchForm ユーザー情報リスト検索条件
	 * @param srchOrderForm ユーザー情報リスト昇順降順条件
	 * @param mode モード
	 * @param model モデル
	 * @param pageable ページ
	 * @return 遷移先
	 */
	@PostMapping(params="mode=list")
	public String userList(UserSrchForm userSrchForm,
			SrchOrderForm srchOrderForm,
			@RequestParam("mode") String mode,
			Model model, 
			@PageableDefault(
					  			size=pageableDefaultSize
	                          ) 
			  Pageable pageable) {
		return (String)userListComm(null, userSrchForm, srchOrderForm, model,pageable, false);
	}
  
	/**
	 * ユーザー情報リスト一覧表示処理(PC・WEB用)
	 * 検索ボタン押下により、ユーザー情報リスト一覧を表示する処理
	 * 
	 * @param userSrchForm ユーザー情報リスト検索条件
	 * @param result チェック結果
	 * @param mode モード
	 * @param model モデル
	 * @param pageable ページ
	 * @return 遷移先 
	 */
	@PostMapping(params="mode=list_do")
	public String userListDo(@Validated(GroupOrder.class) UserSrchForm userSrchForm,
			BindingResult result,
			@RequestParam("mode") String mode,
			Model model, 
			@PageableDefault(
		  			size=pageableDefaultSize
                ) 
		  Pageable pageable) {
		return (String)userListDoComm(null, userSrchForm, result, model, pageable, false);
	}
  
	/**
	 * ユーザー情報リスト一覧表示処理(PC・WEB用)
	 * ページリンク押下により、ユーザー情報リスト一覧を表示する処理
	 * 
	 * @param mode モード
	 * @param model モデル
	 * @param pageable ページ
	 * @return 遷移先 
	 */
	@PostMapping(params="mode=list_back")
	public String userListBack(
			@RequestParam("mode") String mode,
			Model model, 
			@PageableDefault(
				  			size=pageableDefaultSize
                          ) 
			Pageable pageable) {
		return (String)userListBackComm(null, model, pageable, false);
	}


	/**
	 * ユーザー情報リスト一覧表示処理(PC・WEB用)
	 * テーブル項目リンク押下により、ユーザー情報リスト一覧を表示する処理
	 * 
	 * @param srchOrderForm ユーザー情報リスト昇順降順条件
	 * @param result チェック結果
	 * @param mode モード
	 * @param model モデル
	 * @param pageable ページ
	 * @return 遷移先 
	 */
	@PostMapping(params="mode=list_up_dwn")
	public String userListUpDwn(@Validated SrchOrderForm srchOrderForm,
			BindingResult result,
			@RequestParam("mode") String mode,
			Model model, 
			@PageableDefault(
				  			size=pageableDefaultSize
                          ) 
			Pageable pageable) {
		return (String)userListUpDwnComm(null, srchOrderForm, result, model, pageable, false);
	}

	/**
	 * ユーザー情報削除処理(PC・WEB用)
	 * 
	 * @param mode モード
	 * @param id ID
	 * @param model モデル
	 * @param pageable ページ
	 * @return
	 */
	@PostMapping(params="mode=del_do")
	public String userDelDo(@RequestParam("mode") String mode, 
			@RequestParam("id") Long id,
			Model model, 
			@PageableDefault(
		  			size=pageableDefaultSize
                ) 
			Pageable pageable) {
		return (String)userDelDoComm(null, id, model, pageable, false);
	}

	//=======================================================
	// csvダウンロード
	//=======================================================
	/**
	 * csv形式でダウンロードする
	 * 補足:CsvMapperクラスを使う方法にしている。
	 *       文字コードはデフォルトUTF-8 からShift_JISに変更した。
	 *        ①「response.setContentType(MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE + ";charset=Shift_JIS");」としたが、
	 *         UTF-8のままShift_JISにならなかったので、
	 *         「produces = MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE + "; charset=Shift_JIS;"」にした。
	 *        ②producesに「produces = MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=Shift_JIS; Content-Disposition: attachment; filename=\"user.csv\"")」
	 *         としたが、ファイル名が”user.csv”にならなかった。ので
	 *         「response.setHeader("Content-Disposition", "attachment; filename=\"user.csv\"");」にした。
	 */
	@PostMapping(params="mode=csv",
			produces = MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE + "; charset=Shift_JIS;")
    @ResponseBody
    public Object userCsv(HttpServletResponse response) throws JsonProcessingException {
		//SortItemNameとSortOrderの内容をチェック、編集する
		Functions.editSortItemNameOrder(this.sessionUserSrchOrderForm.getSrchOrderForm(), sortItemNames);
		//文字コードと出力するCSVファイル名を設定
		response.setHeader("Content-Disposition", "attachment; filename=\"user.csv\"");
		//検索
		String selectSql = editSql("select");
		List<Object> argsList = getArgsList(this.sessionUserSrchForm.getUserSrchForm());
		List<User> userList = userService.getFindsUser(selectSql, argsList);
		//CSVデータに入れる
		List<UserCsv> userCsvList = new ArrayList<UserCsv>();
        for (User user : userList) {
        	UserCsv usercsv = new UserCsv();
        	//同一プロパティ(型名まで同じもの)コピー
        	BeanUtils.copyProperties(user, usercsv);
        	//コピー先の型が違うものをコピー
        	usercsv.setId(Long.toString(user.getId()));
        	//リストに追加する
        	userCsvList.add(usercsv);
        } 
        CsvMapper mapper = new CsvMapper();
        //すべての項目をダブルクォーテーションで囲む
        mapper.configure(Feature.ALWAYS_QUOTE_STRINGS, true);
        //Date型の編集フォーマットを指定する
        mapper.setDateFormat(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"));
        CsvSchema schema = mapper.schemaFor(UserCsv.class).withHeader();
        return mapper.writer(schema).writeValueAsString(userCsvList);
    }

	/**
	 * userUpCsvメソッド
	 * ユーザーテーブルアップロード画面表示
	 * ユーザーテーブルアップロード画面を表示する
	 * 
	 * @return "/members/admin/user/userUpCsv"
	 */
	@PostMapping(params="mode=up_csv")
	public String userUpCsv() {
	    return "/members/admin/user/userUpCsv";
	}

	//=======================================================
	// csvアップロード
	//=======================================================
	/**
	 * userUpCsvDoメソッド
	 * csvファイルをアップロードし、ユーザーテーブルに登録する処理
	 * アップロードは管理者向けなので、CsvUtils.readにおいて、CsvMapperクラスでパーズし、
	 * userService.registerにおいて、@Validで項目チェックを行っている。
	 * 補足:アップロードする、csvファイルはShift_JISであること。
	 * 
	 * @param file csvファイルアップロード
	 * @param mode モード
	 * @param model モデル
	 * @return "/members/admin/user/userUpCsv"
	 */
	@PostMapping(params="mode=up_csv_do")
	public String userUpCsvDo(@RequestParam("file") MultipartFile file,
			@RequestParam("mode") String mode,
			Model model) {
	    List<UserUpload> userList;
		try {
			userList =CsvUtils.readSjis(UserUpload.class, file.getInputStream());
		} catch(CsvMappingException e) {
			model.addAttribute("errorMessage", "CSVファイルのタイトル行(1行目)と2行目以降の項目数を合わせてください。 メッセージ=" + e.getMessage());
			return "/members/admin/user/userUpCsv";
		} catch (UnrecognizedPropertyException e){
			model.addAttribute("errorMessage", "CSVファイルのタイトル行(1行目)はEntityの項目名(テーブル項目名ではない)にしてください。 メッセージ=" + e.getMessage());
			return "/members/admin/user/userUpCsv";
		} catch(Exception e) {
            e.printStackTrace();
            log.error("エラーが発生しました", e);
			model.addAttribute("errorMessage", "エラーが発生しました");
			return "/members/admin/user/userUpCsv";
	 	}	  
		try {
			userService.register(userList);
		//単項目チェックエラー(『userService.register(@Valid List<UserUpload> userList)』の@Validが出したエラー)	
		} catch(ConstraintViolationException e) {
			List<String> list = Functions.createErrorMessage(e.getConstraintViolations());
			model.addAttribute("errorMessageList", list);
			return "/members/admin/user/userUpCsv";
		//複合項目チェックエラー(自力チックで出したエラー)
		} catch(UploadComplexValidException e) {
	        List<String> MsgList = Functions.getErrorMsgList(e.getHashMap());
			model.addAttribute("errorMessageList", MsgList);
			return "/members/admin/user/userUpCsv";
		//その他の更新時エラー
		} catch(Exception e) {
            e.printStackTrace();
            log.error("エラーが発生しました", e);
			model.addAttribute("errorMessage", "エラーが発生しました");
			return "/members/admin/user/userUpCsv";
	 	}	  
		model.addAttribute("successMessage", "ユーザー情報登録が完了しました");
		return "/members/admin/user/userUpCsv";
	}
}

■修正後のUserFForm.java

package com.kaz02u.demo.fForm;
import java.io.Serializable;
import javax.validation.Valid;
import org.springframework.stereotype.Component;
import com.kaz02u.demo.form.UserForm;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

@Data
@EqualsAndHashCode(callSuper=false)
@NoArgsConstructor
@AllArgsConstructor
@Component
public class UserFForm implements Serializable {
	
	/**
	 * ユーザー情報Form(Flutter用) 
	 */
	private static final long serialVersionUID = 1L;

	@Valid
	private UserForm userForm;
	private String roles; //ロール(詳細表示用)
	private FormComm formComm;

}

■修正後のFormComm.java

package com.kaz02u.demo.fForm;

import java.io.Serializable;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class FormComm implements Serializable {
	
	/**
	 * 共通Form(Flutter用)
	 */
	private static final long serialVersionUID = 1L;

	private String mode;
	private String _csrf;
	private Integer page;

}

■修正後のUserSrchFForm.java

package com.kaz02u.demo.fForm;

import java.io.Serializable;

import javax.validation.Valid;

import org.springframework.stereotype.Component;

import com.kaz02u.demo.form.SrchOrderForm;
import com.kaz02u.demo.form.UserSrchForm;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

@Data
@EqualsAndHashCode(callSuper=false)
@NoArgsConstructor
@AllArgsConstructor
@Component
public class UserSrchFForm implements Serializable {
	
	/**
	 * ユーザー情報検索Form(Flutter用)
	 */
	private static final long serialVersionUID = 1L;
	@Valid
	private UserSrchForm userSrchForm;
	@Valid
	private SrchOrderForm srchOrderForm;
	private FormComm formComm;
}

■修正後のSrchOrderFForm.java

package com.kaz02u.demo.fForm;

import java.io.Serializable;

import javax.validation.Valid;

import org.springframework.stereotype.Component;

import com.kaz02u.demo.form.SrchOrderForm;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

@Data
@EqualsAndHashCode(callSuper=false)
@NoArgsConstructor
@AllArgsConstructor
@Component
public class SrchOrderFForm implements Serializable {
	
	/**
	 * ユーザー情報検索昇順降順Form(Flutter用)
	 */
	private static final long serialVersionUID = 1L;
	@Valid
	private SrchOrderForm srchOrderForm;
	private FormComm formComm;

}

④Flutter画面

ログインボタン押下でメニュー画面

ユーザー情報登録ボタン押下でユーザー情報登録画面



値を入力し、登録ボタン押下でユーザー情報登録完了

←ボタン押下でメニュー画面

ユーザー情報一覧(更新削除)ボタン押下でユーザー情報一覧画面



値を入力し、検索ボタン押下でユーザー情報一覧画面

詳細ボタン押下でユーザー情報詳細画面

更新ボタン押下でユーザー情報更新画面



値を入力し、登録ボタン押下でユーザー情報一覧画面。更新完了

削除ボタン押下でダイヤログ表示

OK押下でユーザー情報一覧画面。削除完了

⑤Pc画面は省略。

■2022/06/15に、勉強した成果:『Flutter_JavaSpringプログラム自動作成◎自動生成ツール』をVectorに載せました。Zenn本も書きました。使ってみての感想や間違いの指定や、こうやったほうがいいとかの情報があればメールください。
Vector
www.vector.co.jp
・Zenn本(Flutter_JavaSpringプログラム自動作成)
zenn.dev