LoginSignup
0
0

More than 1 year has passed since last update.

初めてSpring BootでHello Worldするときに出会ったエラー

Last updated at Posted at 2021-07-01

参考書籍

EclipseにSpringがインストールされているかどうかの確認方法

EclipseにLombokが入っているかの確認方法

コントローラとhtmlファイルを作ったが、HelloWorldできない!
そもそもローカルホストとどうやって繋がっているのか謎

書籍とディレクトリ構造が違った
(のちのち混乱しないために)新規プロジェクトを作った時、設定でパッケージ名を書籍と合わせること
例:書籍ではパッケージ名が「com.example」だったが、自環境で作成するとデフォルトが「com.example.demo」となっていた。

初めに作ったパッケージの中にmainメソッドを持つjavaファイルが作成されるが、
そのファイルと同じパッケージかそれ以下の階層にないとコントローラがうまく働かないっぽい?

書籍ではHelloWorld表示のために新規作成したパッケージがhelloと表示されているが、
com.exampleパッケージの下の階層となるので作成するときの正式名は「com.example.hello」

書籍ではH2データベースを使っているが、MySQLを使いたい!
接続するために必要なライブラリは何?
Springを使わない場合はビルドパス構成で通していたけど・・・
application propertiesに記述する接続情報はH2とどう違うのか?
→ライブラリをMySQLに変更して、application.propertyの中をmySQL仕様に変える
MySQLが使用しているポート番号はDBViewerで確認した
(DB名を右クリック→編集→次へ、で表示される内容)
MySQLのポート番号と、server.port(8080)のポート番号は違うので注意
ripository.javaの中でJdbcTemplateを使用し、接続処理

tymeleafのメッセージ式が表示されない!
resource配下にmessage.propertyを作成し、メッセージを登録
th:text="#{キー名}"で表示させようとしてもうまく表示されない
ブラウザ上の表示は「??キー名_ja??」のようになっている
→Ecripseを再起動させると正常に表示された


2021.07.22
英文エラーで目が泳がなくなってきたことや、System.out.printlnの多用でエラーの原因を推察できるようになってきた。
そんな中、半日溶かしたエラーをメモしておく。

期待する動き
・ユーザー一覧からリンクでユーザー情報を示したページへ遷移(*1:パラメータを渡しコントローラでユーザー情報検索)
・ユーザー情報ページにある編集リンクを押すと編集ページへ遷移(*2:パラメータを渡す)
・編集ページはフォームを表示、フォーム内に現在の情報をvalueで表示、送信ボタンでユーザー情報ページへ(*3:ユーザー情報の入ったdtoを渡す)

1と*3では同じようにユーザ情報ページへ遷移するものの、
*1はリンクに埋めたuser_idをパラメータを使用、
2は編集メソッドからuser_idを受け取りreturnでユーザー情報にアクセスしなければならない。
ユーザー情報表示メソッドで2通りの受け取り方に対応する記述に難航した。

解決法:
*1ではリンクにパラメータを埋め込み、受け取り側のgetProfileメソッドの引数で@RequestParamを使用してパラメータを取り出した。
*2では、postEditメソッドの引数にRedirectAttributesを入れ、処理でredirectAttributes.addFlashAttribute("キー名", 値);
とすることで1度だけ取り出せる(removeする必要のない)FlashScopeに登録。
受け取り側のgetProfileメソッドで(int) model.getAttribute("user_id")として取り出す。

この時、*2のルートだと@RequestParamをつけた引数に該当するものがなく、「No primary or single public constructor found for int - and no default constructor found either(該当するコンストラクタがない)」となる。

パラメータの受け取りはデフォルトだと必須になっているため、受け取りを任意にしたい場合は以下のように指定する。
(@RequestParam(name = "id", required = false) Integer id)
@RequestParamでパラメータを受け取らなかった場合idに入る値はnullとなるため、型はintでなくIntegerにする。

getProfileメソッド内で*1、*2どちらのidが存在するかif文で確認し、nullでない方のidを使用してユーザー情報のdtoを入手する。
なお、int型はInteger型にキャストしなければnull判定できないため注意する。

半日溶かしたポイント:
RedirectAttributes、redirectAttributes.addFlashAttribute("キー名", 値)の取り出しかたを調べると、受け取り側の引数:今回だとgetProfileメソッドで(@ModelAttribute("キー名") int id)と記述して取り出す方法が出てきて初めにこちらを試していたものの、@RequestParamと併用すると引数の違いの問題が出てきてしまった。
つまり、@RequestParamは引数として受け取るかどうか選択できるが、@ModelAttributeは引数に設定してしまうと必ず受け取らなくてはいけなくなり、*1ルートの際に「該当するコンストラクタがない」というエラーが出る。
この兼ね合いに気付くのに時間がかかった。


フォーム編集画面で登録済み情報をフォーム内にデフォルト表示させるとき、
例)
th:field="text" th:value="default_text"
のようにtymeleafのth:objectを使用してth:fieldが記述されていると、
th:valueの内容が無視される。
th:valueを記述したいときは
name="text" id="text" th:value="default_text"
とすること。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0