フロント側を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