7's workspace

業務外にSpringBootを使ってWebアプリを完成させるまでの記録

【第5回?】色々すっとばして、完成

【第5回】

動くものができました

「Poi」の完成までの流れは、

  1. 画面遷移するだけのベースを作る

  2. 新規登録機能を作る

  3. ログイン機能を作る

  4. メモの登録、編集、削除機能を作る

  5. フロント側を作る

だったのですが、2〜5は細かくブログを書くことなく 作りきってしまいました。

完成したものをHerokuにアップしています。

【Poi】

https://poi-777.herokuapp.com/

レスポンシブデザインなのでスマホでも見れます。

PC用のWebアプリにしようと思ってましたが、 スマホで見た時のレイアウトも結構お気に入りです。

アプリ公開までの苦労

1〜5の作業中もなかな苦労したのですが、 できたものをHerokuに公開することにも苦労しました。

( ˘ω˘)『チュートリアルだとできるのに 自分のアプリだとうまくいかない...』

結局は設定ファイルの問題だったのですが、

コンテキストパスの設定だとか 「application.yml」と「application.properties」の書き方の違いとか ProcFileに記述するjarの実行方法とか

色んなことが分かってなかったです。 (今も完全に分かったとは言えないので、そこは今後の課題です。)

今後

本来は完成に至るまで、つまったところなどを ブログにアップするのが目的だったのですが

作ってると夢中になってしまいました。 (ブログのサブタイトルが悲しい...)

ところどころメモを残していたので そのうちアップするかも。

今後の技術メモは「Poi」で。

とか言えるくらいにバージョンアップしたいものです。

とりあえずは作りきれて良かった! おつかれさまでした。

【第4回】画面遷移②

パスの管理をまとめる

前回は、一通りの画面遷移ができるよう Controllerとhtmlファイルを作成しました。

その時に気になるのがパスです。

パスは開発中に変更がある可能性が高いので

管理しやすいように一つのクラスにまとめておきましょう。

poi
├─ src/main/java
│   └─ poi
│        ├─ constant
│        │    └─  UrlConstant.java

(省略)

constant(定数)パッケージを作り、

その中に"UrlConstant.java"を作成しました。

主に「画面」「コントローラ」で分けて、

さらに一般用・会員用・エラー用に分けています。

一部抜粋です。

public final class UrlConstant {

    /** 画面. */
    public static class Page {

        private static final String MEMBER = "member";

        private static final String GENERAL = "general";

        /** 会員. */
        public static class Member {

            /** ログイン画面. */
            public static final String LOGIN = MEMBER + "/login";
            /** TOP画面(検索). */
            public static final String TOP = MEMBER + "/top";

    /** 一般. *
                       ・・・


  (省略)



    /** コントローラー. */
    public static class Controller {

        public static final String MEMBER = "/member";

        public static final String GENERAL = "/general";

        /** 会員. */
        public static class Member {

            /** ルート */
            public static final String ROOT = MEMBER + "/";

            /** ログイン画面. */
            public static final String LOGIN = MEMBER + "/login";

    /** 一般. */
                       ・・・


  (省略)


このようにまとめておくと、

Controllerの記述が変わります。

【前回のRegisterController】

@Controller
public class RegisterController {
    @RequestMapping(value = "/general/register", method=RequestMethod.POST)
    public String register() {
        return "general/register";
    }

【今回のRegisterController】

@Controller
public class RegisterController {
    @RequestMapping(value = UrlConstant.Controller.General.REGISTER, method = RequestMethod.POST)
    public String register() {
        return UrlConstant.Page.General.REGISTER;
    }

定数の部分にカーソルを当てると、

該当のパスが表示されます。

修正したい時は、

「command + クリック」でUrlConstant.javaに飛んで

修正すればスムーズです。

コンテキストパスの設定

話が飛びますが、

コンテキストパスを、プロパティファイルに設定しておきます。

前回までは初期表示(index.htmlの表示)する"GeneralIndexController.java"のパスは

@RequestMapping("/poi")

となっていて、

アクセスする時は「localhost:8080/poi/」にアクセスしていました。

コンテキストパスも変更がある可能性があるので、

コードの外に出しておくとよいでしょう。

application.propertiesに、以下のように記述します。

server.port=8080
server.session.timeout=900
server.contextPath=/poi

ここにコンテキストパスを設定し、

先ほどの"GeneralIndexController.java"のパスは

@RequestMapping(value = UrlConstant.Controller.General.ROOT, method = RequestMethod.GET)

に変更します。

先ほどのUrlConstantで、一般のルートを/general/ に設定したので、

アクセスする時は「localhost:8080/poi/general/」にアクセスしましょう。

設定ファイルの書き方はこちらを参考に。

https://meihaogit.github.io/java/2016/09/01/Spring-boot.html

https://www.slideshare.net/makingx/grails-30-spring-boot

さて、次回は新規登録画面の作成です。

DBの設定の話になるかもしれません。

では今回はこの辺で。

【第3回】画面遷移①

アプリのベースを作る

今回は画面遷移です。

ただただ、アプリに必要な画面を遷移できるようにしました。


ブログ風ナレッジ置き場「Poi」の完成まで

  1. 画面遷移するだけのベースを作る

  2. 新規登録機能を作る

  3. ログイン機能を作る

  4. メモの登録、編集、削除機能を作る

  5. フロント側を作る


「1. 画面遷移するだけのベースを作る」のところです。

作業としては単純で、

同じようなhtmlファイルとControllerを作るだけなのですが、

この作業が意外と重要です。

はじめに画面遷移を完成させておくメリット

なぜ最初に画面遷移を完成させるかというと、

開発中の無駄な戻りを防ぐためです。

チーム開発で、メンバーがそれぞれ別の機能を担当するとします。

いざ、それぞれが作った画面をつなげる時になって

「あれ・・・パスが違うみたいでつながりません・・・」

なんてことになると、作業が止まってしまいます。

はじめに画面遷移のベースができていれば、

そのベースを元にメンバーが作業することでスムーズな開発ができます。

ベースはチームのリーダーが作っておくと

その後の作業も管理しやすいと思われます。

ディレクトリ構造を意識してパッケージング

第2回で、gradleを使ってプロジェクトを作成した時は

HelloControllerとhello.htmlがあるだけでした。

今回はたくさんControllerとhtmlファイルを作りましたが、

「poi」は会員制のブログのようなものなので、

一般と会員でパッケージが分かれるようにしています。

poi
├─ src/main/java
│   └─ poi
│        ├─ controller
│        │   ├─ general
│        │   │   └─ GeneralIndexController.java
│        │   │   └─ RegisterController.java
│        │   ├─ member
│        │   │   └─ MemberIndexController.java
│        │   │   └─ LoginController.java
│        │   │   └─ KnowledgeController.java
│        │   ├─ ErrorController.java
└─ src/main/resources
     ├─ templates
     │   ├─ general
     │   │   └─ index.html
     │   │   └─ register.html
     │   │   └─ confirm.html
     │   ├─ member                        
     │   │   └─ index.html
     │   │   └─ login.html
     │   │   └─ create.html
     │   │   └─ update.html
     │   │   └─ delete.html
     │   │   └─ complete.html
     │   └─ error 
     │        ├─ 404.html
     │        └─ session-timeout.html
     ├─ static
     │   ├─ css
     │   └─ js
     └─ application.properties

作成したもの

一部だけ載せるとこんな感じです。

<confirm.html> 新規登録画面で情報入力後に表示される確認画面。
「OK!」ボタンをクリックすると、
form actionのパス「/general/create」から
“RegisterController.java"のパス「/general/create」へ飛ぶ。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
<meta charset="UTF-8" />
<title>poi</title>
</head>

<body>
    <h1>Confirm</h1>
    <form action="/general/create" method="post">
        <input type="text" /> <input type="submit" value="OK!" />
    </form>
</body>

</html>

<RegisterController.java> “confirm.html"からここへくる。
「return "member/index”;」で会員画面のindex.htmlへ
遷移する。

package poi.controller.general;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class RegisterController {
    @RequestMapping(value = "/general/register", method=RequestMethod.POST)
    public String register() {
        return "general/register";
    }
    @RequestMapping(value = "/general/confirm", method=RequestMethod.POST)
    public String confirm() {
        return "general/confirm";
    }
    @RequestMapping(value = "/general/create", method=RequestMethod.POST)
    public String create() {
        return "member/index";
    }
}


今回はここまで。
次回、画面遷移②です。

今、パスをベタ書きしているので、定数クラスを作成して
パスを定数化しようと思います。

【番外編】Gitの使い方

まとめてみた

肝心のWebアプリ作成がそんなに進んでいませんが、
今回は番外編としてGitを使ったバージョン管理について
勉強したいと思います。

というのも、新入社員向けに行った勉強会で
Gitの使い方を担当したので、そのまとめになります。

新入社員向け、という名目でしたが
自分が一番勉強になりました。

それではさっそく、始めましょう!

Gitを図で確認!

Gitについて一目でわかるのがこちらの図。

f:id:it7db:20170527071159p:plain

※資料を作っていただきました!(id:marikooota)
Gitポケットリファレンスの「Git作業フロー&コマンドチートシート」を参考にしています!

この図に書いてあることが本当にそのままで、
もし一歩踏み込んだ操作をしないのであれば
普段使いにはこれだけで十分なんじゃないかと思います。

自分が研修受けてた頃は、pull, add, commit, pushの4種類だけでなんとかやっていました。
※逆に言えばそれしか自信を持って使えなかったです。

ローカルリポジトリを作るのも、共有リポジトリからcloneするのも、
初めの1回だけなのでほとんど記憶がない・・・

今思うのは、自分のペースでいいので一から作ってみるのが最適だということです。

まずは2人でやってみよう!

勉強会ではgitの基本操作を二人ペアで確認してもらいました。
ローカルリポジトリで作業して、リモートリポジトリにプッシュ、マージするところまでやります。

★作業環境・・・GitのインストールとGitHubへのアカウント登録が完了している状態

お題はコーヒーショップです。
Aさん、Bさんに分かれます。

基本操作の確認

まずはGitHubで、リモートリポジトリを作成しましょう!(Aさんが作る)

GitHubにログインして、右上の「+(Create new…)」ボタンのプルダウンメニューから
「New Repository」を選択。 ”Create a new repository”というページでリポジトリを作成します。

f:id:it7db:20170526075610p:plain

そしたら以下のようなページになるので、
リポジトリの名前を決めましょう。
Create a new repositoryボタンを押したら完了です。

f:id:it7db:20170526075620p:plain

リモートリポジトリができました!(簡単!)
これでネット上に自分のソースを置くことができます!

できたリポジトリのURLは「Clone or Download」から見れます。
Gitではcloneコマンドで、このリモートリポジトリを
自分のマシンに複製することができます。
この複製が、ローカルリポジトリとなります。

Bさんがこのリポジトリを触れるよう、AさんはBさんに権限をあげましょう。
SettingのCollaboratorsで、BさんのGitHubアカウント名を入れて
「add Collaborator」ボタンを押せば承認されます。

f:id:it7db:20170526075634p:plain

では続いてローカルリポジトリを作りましょう。
ここからはターミナルでの操作になります。

Aさん、Bさん、どちらも作業します。
自分のソースを管理したい場所、つまりローカルリポジトリになる場所へ
ディレクトリを作成します。

mkdir -p Docments/work_git(ディレクトリ作成)

cd work_git(作ったディレクトリに移動)

ここで以下のコマンドをうつことで、work_gitディレクトリの中に
リモートリポジトリのコピーが作成されます。  

git clone https://github.com/777it/CoffeeShop.git

llコマンドで「CoffeeShop」ディレクトリができていることを確認しましょう。

cd CoffeeShop

これで準備は完了です。

では、なんでもいいので、Aさんがファイルを作ります。

A  vi top.html

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
  </ul>
</body>
</html>

できたファイルをリモートリポジトリにpush(アップロード)しましょう。

A git add top.html

→インデックスへ。バージョン管理の対象となる。

A git commit -m “Initial commit”

→ローカルリポジトリに変更を反映。

A git push

→リモートリポジトリに変更を反映。

先ほど作成したリモートリポジトリに1commit増えていると思います。

Bさんのローカルリポジトリには、今は何もありません。

リモートリポジトリから、Aさんの変更を取り込みます。

B git pull

→リモートリポジトリの変更記録を、ローカルリポジトリに反映。

これで、Bさんのローカルにもtop.htmlがある状態になりました。

pull = fetch + merge

確認しておきたいのが、fetchの使い方。
pullはfetch(リモートの変更記録をローカルに反映) + merge(作業ツリーに反映)です。

リモートとローカルで競合が起きていた場合、
mergeコマンドをうつとコンフリクトが起きますね。

見方が分かれば、コンフリクトの解消は難しくないのですが、
研修時は「HEAD」がわかっていなかったりして、コンフリクトが恐怖の対象だったりします。(笑)

fetchを使えば、mergeする前に差分を確認することができます。

A vi top.html

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
    <li>オレンジジュース</li>
  </ul>
</body>
</html>

A git commit -a -m “オレンジジュース追加”
A git push

Aさんはtop.htmlにオレンジジュースを追加して、pushします。
リモートリポジトリにはAさんの変更が反映されている状態です。
続いて、BさんはAさんの変更を取り込まないままで、
top.htmlにりんごジュースを追加しましょう。

B vi top.html

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
    <li>りんごジュース</li>
  </ul>
</body>
</html>

B git commit -a -m “りんごジュース追加”

ここで、Bさんはfetchコマンドを使ってみましょう。

B git fetch
B git diff HEAD..FETCH_HEAD

ローカルのHEADとフェッチしてきたリモートのHEADの差分が表示されます。
HEADというのは、作業しているブランチの最新の状態を表しているので、
このコマンドでは、Bさんのローカルの最新の状態と、
fetchしてきたリモートの最新の状態を比較した、という意味になります。

diff --git a/top.html b/top.html
index 2fd2495..40cc4e3 100644
--- a/top.html
+++ b/top.html
@@ -5,7 +5,7 @@
     <li>ブレンドコーヒー</li>
     <li>アメリカン</li>
     <li>水<li>
-    <li>りんごジュース</li>
+    <li>オレンジジュース</li>
   </ul>
 </body>
 </html>

差分を確認すると、Bさんのtop.htmlには
オレンジジュースがなく、りんごジュースが追加されていることがわかります。

今回は、オレンジとりんご、どちらのジュースも追加することにします。 差分を確認して、おかしいところがないようなので、mergeしましょう。

B git merge

Auto-merging top.html
CONFLICT (content): Merge conflict in top.html
Automatic merge failed; fix conflicts and then commit the result.

コンフリクトが起きます。

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
<<<<<<< HEAD
    <li>りんごジュース</li>
=======
    <li>オレンジジュース</li>
>>>>>>> refs/remotes/origin/master
  </ul>
</body>
</html>

<<<<<<< HEADから=======までは
作業ブランチの最新の状態を表しています。

=======から>>>>>>> refs/remotes/origin/masterまでは
リモートのマスターブランチの最新の状態ですね。

<html>
<body>
  <h1>まろ's コーヒー</h1>
  <ul>
    <li>ブレンドコーヒー</li>
    <li>アメリカン</li>
    <li>水<li>
    <li>りんごジュース</li>
    <li>オレンジジュース</li>
  </ul>
</body>
</html>

目印となっている<<<<<<< HEADなどを消して、保存し、リモートへ反映します。

viで作業している場合は、 ddコマンドで、カーソルがある行を切り取りできるので使ってみてください。

B git commit -a -m "コンフリクト解消”
B git push

リモートリポジトリに変更が反映されました。

A git pull

Aさんがpullしてくると、
オレンジジュースとりんごジュースがあるtop.htmlになっているはずです。

ブランチで作業してみよう

文字に起こすのは大変ですね。   少し時間が惜しいので、使ったコマンドをまとめるだけにしてみます。

git branch

自分がどのブランチにいるか確認できる。
今いるプランチには色が付き、星がついている。

git checkout -b topic

ブランチをきる。ここでは「topic」というブランチをきっている。
自動的にブランチが切り替わる。

git commit --amend

直前のコミットを修正できる。
コミットメッセージを誤送信した場合などに、修正ができるのはありがたい。

git rebase

ある時点でのコミットをベースに分岐したブランチの、分岐元を変更できる。
分岐元で新たに変更があった場合に
分岐元を最新のコミットにつなぎ変えることで、
ブランチ側でコンフリクトを解消できるというメリットがある。

– 紹介したかったけどできなかったコマンド –

git add reset

インデックスに登録したファイルを、コミット対象から外すことができる。
誤ってインデックスにファイルをあげてしまった時などに使用する。

git revert

コミットの内容を取り消すコミットを実行する。
取り消したいコミットを指定すると、
コミットを取り消すことができる。

git cherry-pick

他のブランチのコミットを、現在のブランチに取り込むことができる。
他のブランチの一部分だけが欲しい場合などに使用する。

コマンドは覚えなくても、、、

Gitの勉強をして、知らないコマンドにたくさん知りました。
多く覚えるのに越したことはないけれど、
ネットで検索したら必ず該当するコマンドが出てくると思うので、
「こういうことができるコマンドがあったな・・・」とイメージできるくらい
になっておけば良いかなと思います。

お世話になった本

「Gitポケットリファレンス」

Gitポケットリファレンス

Gitポケットリファレンス

→改訂版が出ていました! こっちだとSourceTreeとかの解説が載っているみたいです。

【改訂新版】Gitポケットリファレンス

【改訂新版】Gitポケットリファレンス

「開発ツール徹底攻略 Git/GitHub/Jenkins/Vim/Emacs

開発ツール徹底攻略 (WEB+DB PRESS plus)

開発ツール徹底攻略 (WEB+DB PRESS plus)

今回は、このへんで。

【第2回】Gradleでプロジェクト作成

【第2回】

Gradleでプロジェクト作成

ブログ風ナレッジ置き場「Poi」の完成までの流れは、

  1. 画面遷移するだけのベースを作る

  2. 新規登録機能を作る

  3. ログイン機能を作る

  4. メモの登録、編集、削除機能を作る

  5. フロント側を作る

ざっくりとこんな感じにしようと思います。

5.のフロント側については、頭の中でイメージがぽんぽん出てくるので

サーバ側の実装中に割り込みで入れることもあるかと思います。

(気分転換、大事!)

ではさっそく、「1. 画面遷移するだけのベースを作る」を始めましょう。

といいたいところですが、、、

プロジェクト作成をGradleを使ってやりたい、というものの

Gradleの基礎がわかっていなかったので上記サイトで一通り見直しました。

Gradleの使い方を確認

自分の環境に合わせて少し変更しながら確認。

例えばここではJavaのバージョンが1.7.0_40

「build.gradle」が以下のようになっていましたが、

自分はJava8を使うので、1.6のところは1.8に変更する、など。

apply plugin: 'java'

sourceCompatibility = '1.6' // -source
targetCompatibility = '1.6' // -target

あと余談ですが、「Eclipse のバージョンは Juno・・・」という表記があって、

そういえばEclipseのバージョンにどんなものがあったか

詳しく知らないなぁと思って見直しました。(自分はMarsから知ったのでJunoって?となりました)

次、2017年6月には「Oxygen」(酸素)が出る予定なんですね〜。

ひっかかった点

このGradleの復習中にひっかかった点は、以下2点。

  1. JavaDocを作成するところで、文字化けが起こった

  2. warファイルのデプロイ作業がうまくいかなかった

順に見ていきます。

文字化け対策

まず、「1. JavaDocを作成するところで、文字化けが起こった」について・・・

検索したら解決方法がすぐ出てきました。

qiita.com

build.gradleに以下を設定することで解決しました。

javadoc {

    options.charSet = 'UTF-8'

    options.encoding = 'UTF-8'

}

ちなみに、ターミナルの文字コード確認するコマンドはこちら。

echo $LANG

ja_JP.UTF-8

Tomcatにデプロイする

次に、「2. warファイルのデプロイ作業がうまくいかなかった」について・・・

Webアプリケーションをデプロイする作業です。

めったにやらないので知識がすごく曖昧でした…

(結局、index.htmlの配置フォルダが間違っていたというオチ。)

index.htmlを置く位置は、

/src/main/webappの直下です。

 ※ここがウェブアプリケーションのソースフォルダになります

gradle warコマンドで、正しくwarファイルができたら

build/libsに作成されたwarファイルを、Tomcatのwebapps直下に配置します。

この作業を「デプロイ」といいます。

Tomcatのwebapps直下にwarファイルを置くと、Tomcatがwarファイルを自動展開して、

同じ階層にwarファイルと同名のフォルダを作成します。

 ※これがWebアプリケーションのコンテキストパスになります

webapps/hello/

webapps/hello.war

そして、Tomcatはできたフォルダ(コンテキストパスの方)を読み込んでWebアプリケーションを実行します。

(参考URL)

[http://d.hatena.ne.jp/ozuma/20131227/1388151846:title]

[https://garafu.blogspot.jp/2016/05/how-to-deploy-tomcat-webapp.html:title]

今回のbuild.gradleを作成

ざっと確認できた時点で、「Poi」用のbuild.gradleを作成しました。

buildscript {
  ext {
    springBootVersion = '1.4.3.RELEASE'
  }
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    classpath("org.springframework:springloaded:1.2.5.RELEASE")
  }
}

apply plugin: "java"
apply plugin: "spring-boot"
apply plugin: "eclipse"

repositories {
  mavenCentral()
}

dependencies {
  compile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
  // Test
  testCompile("org.springframework.boot:spring-boot-starter-test:1.2.1.RELEASE")
}

compileJava {
  options.encoding = 'UTF-8'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

javadoc {
    options.charSet = 'UTF-8'
    options.encoding = 'UTF-8'
}

task wrapper(type: Wrapper) {
  gradleVersion = '2.9'
}

シ、シンプル・・・

PostgresとかDoma2とか、依存関係の部分に追加していく予定です。 追加したらまた改めてアップします。

今回Gradleの使い方を確認したことで、 Webアプリのディレクトリ構成とかTomcatについても復習になって とても良かったなぁと思います。

ターミナルで使うコマンドとか、 Markdownの使い方も調べ直したり…

(記事の見やすさについても研究せねば。)

それはさておき。 プロジェクトができて、やっとスタート地点に立てました。

次回は、「①画面遷移するだけのベースを作る」に入ります。

【第1回】はじめに+ブログ風ナレッジ置き場「Poi」画面イメージ

【第1回】

はじめに

 

 時代がPCからスマホに流れていますが、

まだまだWebアプリケーションも使われると思います。

業務でJavaを使わないまま日々が過ぎているので

リハビリに会員登録機能付きのWebアプリケーションを作成します。

 

自分用のメモをカテゴリ分けして保存しておける、

そんな簡単なアプリにしようと思います。

 

その名も「Poi」(ぽい)

 

会員トップ画面からカテゴリを選択すると

メモ一覧が表示され、見たいメモを見ることができる。

ナレッジ(金魚)をポイ(検索機能)で拾い上げるイメージ…。

プロジェクト名、何にしよう?→ぱぴぷぺぽ入ってると軽くていいな→「ぽい」とか、ちょっと抜けてていいな…→ぽいってなんだっけ?→あぁ金魚すくいのアレか→虫めがねみたい→虫めがねといえば検索→ブログ内検索→ちょうどいいね(^ω^)!

 

発想が小学生なので、小学生向けに作りたいと思います。

-----------------------------------------------------------

使用する技術(予定)

Java8、SpringBoot、Doma2、gradle、PosrgreSQL

-----------------------------------------------------------

以下、簡単な画面遷移イメージです。

f:id:it7db:20170501203956p:plain

 作る上でつまづいた点などを記事にできたらと思います。
よろしくお願いします。

DTOに格納した値がDBに登録されない

画面遷移がある会員登録機能で、

各画面で入力項目をDTOにつめて、セッションに保存しようとしていた。

 

最後にサービスからDAOを呼び出すのだが

DBに保存されない。

 

@Controller

public class AccountController extends BaseController {

 

@Autowired

SessionDto sessionDto;

 

・・・

 

/**

* 新規登録画面(詳細)で入力した値がModelにセットされる 新規登録画面(確認)へ遷移する

*/

@RequestMapping(value = UrlConstant.Controller.General.CREATE_CONFIRM, method = { RequestMethod.POST })

public String createConfirm(@Validated DetailForm detailForm, BindingResult result, Model model) {

model.addAttribute("msg", "以下の内容でよろしいですか?");

if (result.hasErrors()) {

return UrlConstant.Page.General.CREATE_DETAIL;

}

BeanUtils.copyProperties(detailForm, sessionDto);

return UrlConstant.Page.General.CREATE_CONFIRM;

}

 

/**

* 前画面までに入力された値をDBに登録する 登録処理後、会員画面へ遷移

*/

@RequestMapping(value = UrlConstant.Controller.Member.ROOT, method = { RequestMethod.POST })

public String create_and_displayindex(Model model) {

model.addAttribute("msg", "登録完了です!");

daoService.registerUser(sessionRegisterDto);

return UrlConstant.Page.Member.INDEX;

}

 

結局の原因は、create_and_displayindexの引数部分に(@Validated SessionDto dto,BindingResult result, Model model)みたいにセットしていたから。

 

コピーするのはいいが、こういう風におかしなセットしないように注意。