kazpgmの日記

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

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

21:41
①バックエンドSpringBootを使っての画像保存を調べる。の、つづき。やっとバックエンドSpringBoot側で画像保存できた。こんな感じ。
まず、ファイルアップロードサイズ指定が小さかったので、大きくした。(具体的にはapplication.propertiesを修正)
■application.propertiesを修正

<<修正前>>
#UPLOADファイルMAXサイズ
spring.servlet.multipart.max-file-size=1MB
spring.servlet.multipart.max-request-size=10MB
<<修正後>>
#UPLOADファイルMAXサイズ
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=50MB

スマホの画像情報登録画面

ファイルホルダをクリックする。

画像を選択する。画像が表示される

登録ボタンを押下すると、バックエンドSpringBootで画像保存し完了メッセージが来る。

■バックエンドSpringBoot側、画像登録後のUPLOADフォルダに画像が保存された

1.スマホ側Flutterプログラム抜粋

  _mode = (_gazoForm.messageForm.mode == 'ins' || _gazoForm.messageForm.mode == 'ins_do')?'ins_do':'upd_do';
  widget.headers["content-type"]= "multipart/form-data";
  widget.headers["X-XSRF-TOKEN"]= "${widget.cookies['XSRF-TOKEN']}";
  final url = Uri.parse("${Consts.myHttpUrl}/members/admin/gazo/gazo/" + _mode);
  var request = http.MultipartRequest("POST", url);
  request.fields['formComm.page'] = _gazoForm.messageForm.page.toString();
  if (_gazoForm.gazoFlFile != null) {
    final mimeTypeData = lookupMimeType(
     _gazoForm.gazoFlFile!.path, headerBytes: [0xFF, 0xD8])!.split('/');
    final file = await http.MultipartFile.fromPath(
     'gazoForm.gazoFlFile', _gazoForm.gazoFlFile!.path,
     contentType: MediaType(mimeTypeData[0], mimeTypeData[1]));
    request.files.add(file);
  }
  request.headers.addAll(widget.headers);
  final streamedResponse = await request.send();
  response = await http.Response.fromStream(streamedResponse);
   }
   if (response.statusCode != 200) {
  setState(() {
    int statusCode = response.statusCode;
    if (response.statusCode == 401 || response.statusCode == 403) {
   _errorSuccessMsg = "ログインしてください";
    } else {
   _errorSuccessMsg = "エラーが発生しました $statusCode";
    }
  });
  // 画面を先頭に戻す
  _scrollController.animateTo(0,
   duration: const Duration(milliseconds:600),
   curve: Curves.easeInQuint);
  return;
   }
   CommUtils.updateCookie(response, widget.cookies, widget.headers);
   // response.bodyをutf8でdecodeする。
   String _resData = utf8.decode(response.body.runes.toList());
   if (kDebugMode) {
  print(_resData);
   }
   // バックエンドで例外発生の場合MessageFormの値しか戻らないため、ここで確認する
   MessageForm _messageForm = MessageForm.initData();
   _messageForm.fromJson(_resData);
   // SpringBootで例外発生の場合
   if (_messageForm.mode =="SystemError") {
  // エラー画面
  Navigator.of(context).push(
    MaterialPageRoute(
   builder: (context) => Error(title: widget.title, username: widget.username,
    headers: widget.headers, cookies: widget.cookies, resData: _resData),
    ),
  );
  // 正常処理
   } else {
    setState(() {
   _gazoForm.fromJson(_resData);
   _errorSuccessMsg =
    _gazoForm.messageForm.errorMessage + _gazoForm.messageForm.successMessage;
   if (_errorSuccessMsg == '' &&
      _gazoForm.messageForm.itemErrorMessages != '') {
     _errorSuccessMsg = '項目エラーを確認してください';
   }
    });
  }
   }
 } catch (e) {
   setState(() {
  _errorSuccessMsg = "エラーが発生しました" + e.toString();
   });
 }
 // 画面を先頭に戻す
 _scrollController.animateTo(0,
  duration: const Duration(milliseconds:600),
  curve: Curves.easeInQuint);
  }

2.バックエンドSpringBootプログラム抜粋
■GazoFlutterController.java

public class GazoFlutterController extends GazoCommController{
・・・
 /**
  * GAZO登録処理(Flutter用)
  * GAZO登録する処理
  *
  * @param gazoFForm Flutter向けGAZO登録
  * @param result チェック結果
  * @param model モデル
  * @return jsonデータ
  */
 @SuppressWarnings("unchecked")
 @PostMapping("/members/admin/gazo/gazo/ins_do")
 @ResponseBody
 public  Map<String, Object> gazoInsDoFlutter(@Validated({GroupOrder1.class, GroupOrder2.class})  GazoFForm gazoFForm,
   BindingResult result,
   Model model) {
  return (Map<String, Object>)gazoInsDoComm(gazoFForm.getGazoForm(), result, model, true);
 }
}

■GazoCommController.java

public class GazoCommController implements Consts{
・・・
 /**
  * GAZO登録処理(Flutter、PC・WEB共用)
  * GAZO登録するする共通処理
  *
  * @param gazoForm GAZO登録
  * @param result チェック結果
  * @param mode モード
  * @param model モデル
  * @param flutterFlg true:Flutter用 false:PC・WEB用
  * @return Flutter用:jsonデータ PC・WEB用:遷移先
  */
 protected Object gazoInsDoComm(GazoForm gazoForm, BindingResult result, Model model, boolean flutterFlg) {
  if (flutterFlg) {
   model.addAttribute("gazoForm", gazoForm);
  }
  //エラーになったときのモードを設定
  model.addAttribute("mode", "ins");
  if (result.hasErrors()) {
   model.addAttribute("errorMessage", "エラーが発生しました");
   model.addAttribute("itemErrorMessages", result.toString());
   return returnComm("/members/admin/gazo/gazoRegister", model, result, flutterFlg, null, "gazoForm", null, null);
  }
  String seqid="";
  List<String> inslist = new ArrayList<String>();
  try {
   String mode = "ins_do";
   //主キー作成
   seqid = seqService.getDbSeq("gazo", gazoSeqidLen, "あり", 6);
   String itemName;
   if (gazoForm.getGazoFlFile() != null) {
    if (!ObjectUtils.isEmpty(gazoForm.getGazoFlFile().getOriginalFilename()) || 
      !ObjectUtils.isEmpty(gazoForm.getGazoFlDel())) {
     itemName = functions.setAndDelUploadFile(gazoForm.getGazoFlFile(),
          "gazo", seqid, "gazoFl", mode, gazoForm.getGazoFlDel());
     gazoForm.setGazoFl(itemName);
     if (!ObjectUtils.isEmpty(itemName)) {
      inslist.add("gazo/" + seqid + "/" + itemName);
     }
    }
   }
   if (gazoForm.getFileFile() != null) {
    if (!ObjectUtils.isEmpty(gazoForm.getFileFile().getOriginalFilename()) || 
      !ObjectUtils.isEmpty(gazoForm.getFileDel())) {
     itemName = functions.setAndDelUploadFile(gazoForm.getFileFile(),
          "gazo", seqid, "file", mode, gazoForm.getFileDel());
     gazoForm.setFile(itemName);
     if (!ObjectUtils.isEmpty(itemName)) {
      inslist.add("gazo/" + seqid + "/" + itemName);
     }
    }
   }
  } catch(Exception e){
   e.printStackTrace();
   log.error("エラーが発生しました", e);
   //エラーになったので、リストしたファイルを削除しておく
   functions.delFileList(inslist);
   throw e;
  }
  try {
   gazoService.register( seqid, gazoForm.getGazoFl(), gazoForm.getFile());
  } catch(Exception e){
   e.printStackTrace();
   log.error("DBエラーが発生しました", e);
   //エラーになったので、リストしたファイルを削除しておく
   functions.delFileList(inslist);
   throw e;
  }
  Gazo gazo = null;
  try {
   //メールのためにGAZOを取得する
   gazo = gazoService.findByPk(seqid);
   if (gazo == null) {
    log.error("gazo not found:pk seqid={}", seqid);
    throw new RuntimeException("invalid pk");
   }
   gazoService.send(appProperties.getMailTo(), appProperties.getMailFrom(), "登録メール", gazo);
  } catch(Exception e){
   e.printStackTrace();
   log.error("メール送信でエラーが発生しました。(但し、GAZOは登録完了済みです)", e);
   model.addAttribute("errorMessage", "エラーが発生しました。(但し、GAZOは登録完了済みです)");
   return returnComm("/members/admin/gazo/gazoRegister", model, result, flutterFlg, null, "gazoForm", null, null);
  }

  gazoInsSub(model);
  model.addAttribute("successMessage", "GAZO登録が完了しました");
  return returnComm("/members/admin/gazo/gazoRegister", model, result, flutterFlg, null, "gazoForm", null, null);
 }

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