初めてのSpring案件を終えたメモ ~MVC編~


はじめに

ピュアJavaとDBの基本知識のみスタートからのSpring案件が波乱の末ひと段落したので、所感や覚書などを。
記事の内容としてはチュートリアル以上、実践未満のイメージ。
掲載コードは動作確認できていないのであくまで参考で。
英語は目が滑るので日本語多様してる、許して。

開発環境

RedHat(開発環境はCent)7系
Java8
SpringBoot2.1.6
MySQL8系
STS

MVCについて

ロジック(Model)と、画面(View)とそれを繋ぐコントローラ(Controller)に分けて設計しましょう、という理解。
でもSpringではViewとControllerでやりとりするデータのことをModelと呼んでいる。
自分がそもそもMVCを理解できていたか不安になったけど、言葉の定義はフレームワークごとに異なるので深く考えるのはやめた。
https://qiita.com/yo1000/items/a6acbf5f454a7f53aef9
https://qiita.com/takasek/items/70ab5a61756ee620aee6

コントローラー

・マッピング
メソッドには@GetMapping("test")とかをつける。@RequestMapping("/test")は古いみたい。

カッコの中に記述するのは属性と呼ぶらしい。上記は@GetMapping(path="test")の省略。
1つのformタグに複数ボタンを配置してPOSTしたいとき、htmlでnameを指定すると、コントローラーのparams属性とマッピングできる。

view.html
<form method="POST" action="path1">
    <input type="submit" name="param1" /> ←こちらを押す
    <input type="submit" name="param2" />
</form>
controller.java
@PostMapping(path="path1",params="param1")

・バリデーション
Springの機能として提供されてる。
BindingResultの操作ができると、フレームワークに縛られないバリデーションが実装できる。
でもアノテーションやカスタムバリデーションを駆使すればほとんどのことはできそう。
https://qiita.com/yakumo3390/items/4e47930ba643b45b7430

メッセージは messages.properties で埋め込み文字や多言語対応も提供してるけど、メッセージをDB管理する要件だったので使えなかった。

グループ属性をつけると、バリデーション対象を指定したり外したりできる。
これのために空のクラスを作ったけど、もっとスマートな方法があるんじゃないかという気持ち。
https://tech.asoview.co.jp/entry/2019/12/11/104928

・return
基本はViewのPathをあらわす文字列。
redirectやforwardもある。
redirectのときはRedirectAttributesに値を詰め込めば遷移先に届く。
http://www.ne.jp/asahi/hishidama/home/tech/java/spring/boot/web/Controller.html#h_forward_attribute

オブジェクトを渡すときはtoString()が実装されていればそのまま渡せる、そうでないときはひと手間いるみたい。
https://grandbig.github.io/blog/2016/05/28/redirect-parameter-spring-boot/

ビューについて

thymeleaf(タイムリーフ)を使用。読みもスペルも難しい。
いわゆるテンプレート。画面だけでなく、生成されるhtmlを確認しておかないとカッコワルイ記述になってたりするので注意。

th:fieldは便利だけどnameやidを指定したいJavaScriptとかと組み合わせるとき使えないこともある。
何をしているか理解しておくといいかも。
https://qiita.com/beeeyan/items/5bd820e55cb53f176b3e

JavaScript内で変数を使うときは慎重に。
例外が発見しにくいのと、オブジェクト丸ごと使うとhtml上に全て展開されてセキュリティ的に良くないし、見たときびっくりする。
公式ドキュメント 12.2 スクリプトのインライン処理 (JavaScript と Dart)

サービスについて

ビジネスロジックを書くところ。

今回は原則1テーブルに対して、1つのサービスを作った。あと汎用クラスをいくつか。
DBへアクセスできる層を絞るのが目的だったけど、そうすると1つのクラスが膨れ上がってしまった。
1画面に対して1つのサービスを作って、DBから取得したデータの加工までRepositoryで行うのがいいのかも。
もしくは、1つの画面に対するロジックを記述する層を追加するか。。。?

他のメモ

初めてのSpring案件を終えたメモ ~Springとは編~
初めてのSpring案件を終えたメモ ~データベース編~