SpringBoot入門
SpringBoot入門してみた
Spring Boot + Thymeleaf
環境
$ sw_vers ProductName: Mac OS X ProductVersion: 10.10.4 BuildVersion: 14E46
$ java -version java version "1.8.0_51" Java(TM) SE Runtime Environment (build 1.8.0_51-b16) Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)
以下のページを参考にしましたm(__)m
- めちゃわかりやすい、チュートリアル記事2つ
- Spring Data JPAでの実装について
- Thymeleafの日本語ドキュメント
http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf_ja.htmlwww.thymeleaf.org
- Spring MVCについて
個人でこれだけまとめるとかすごすぎ・・・
- Springをより詳しく知りたいときに読む
m12i.hatenablog.com http://terasolunaorg.github.io/guideline/5.0.1.RELEASE/ja/terasolunaorg.github.io
- 公式ドキュメント(英語)
- アプリケーションの設定値
http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.htmldocs.spring.io
- 書籍
はじめてのSpring Boot―「Spring Framework」で簡単Javaアプリ開発 (I・O BOOKS)
- 作者: 槇俊明
- 出版社/メーカー: 工学社
- 発売日: 2014/11
- メディア: 単行本
- この商品を含むブログ (5件) を見る
試しに、簡単なアプリケーションを作成してみた。
メモ. その1
Spring Securityで、どうやって認証が行われるのかよくわからなかった。
認証の設定は、SecurityConfig
でしている。
protected void configure(HttpSecurity http)
にて、アクセス認証の設定をしている。
public void configure(WebSecurity web)
では、セキュリティの設定対象外として設定している。
protected void configure(HttpSecurity http)
内でも、.antMatchers("/login/form").permitAll()
で同じようなことをしているが、 違いがわかっていない。。。
static class AuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter
が、一番謎だった。
ざっくりと動作を記述する。
ログイン画面(/login/form)からFormが送信されると、
リクエストパラメータであるmail
の値がLoginUserDetailService#loadUserByUsername(String username)
に渡される。
この時、username
を元にリポジトリ(DB)から対象のデータ(レコード)を取得する。
取得結果が、nullならば存在しないユーザーIDなので例外をthrowする。
存在する場合は、org.springframework.security.core.userdetails.User
を継承した、LoginUserDetail
のインスタンスを返す。
LoginUserDetail
のコンストラクタには、引数として取得したAuthUser
のインスタンスを設定する。
LoginUserDetail
のコンストラクタ内では、org.springframework.security.core.userdetails.User
のコンストラクタを呼び出している。
呼び出しているコンストラクタの引数は、User(String username, String password, Collection<? extends GrantedAuthority> authorities)
となっている。
1, 2番目の引数は見ての通り、username
, password
になっている。
この値が、Formで送信された値と比較される。
パスワードは、SecurityConfig.AuthenticationConfiguration#init(AuthenticationManagerBuilder auth)
内で
設定したpasswordEncoder(getPasswordEncoder())
によって暗号化されて比較されるぽい。
Collection<? extends GrantedAuthority> authorities
については、
よくわかってないが認証したユーザーの権限を渡しているみたい。
わかったら追記。。。
LoginUserDetail
について
LoginUserDetail
は、org.springframework.security.core.userdetails.User
を継承したクラスorg.springframework.security.core.userdetails.User
は、org.springframework.security.core.userdetails.UserDetails
の実装なので、拡張(継承)して使うorg.springframework.security.core.userdetails.UserDetails
は、認証ユーザーの情報を取得するためのAPIを定義したinterface
メモ. その2
CSRFについて。
Spring Securityを有効にすると、デフォルトでCSRF対策が有効になるが、 Thymeleaf側で、正しくform要素を定義しないといけない。
以下のように、<form> ~ </form>
にth:action
属性を追加することで、
自動的に<input type="hidden" name="_csrf" value="e5521ea3-3cc5-4be4-84a5-7acd9ce10987" />
のような
トークンがリクエストパラメータとして追加される。
<form th:action="@{/xxx/xxx}" method="xxx"> ~ </form>
正しく設定されてない場合は、403でエラーとなる。
メモ. その3
Thymeleafでの、バリデーションエラーの表示について。
見たほうがわかりやすい。
<form th:object="${user}" th:action="@{/user/input}" method="POST"> ~ 省略 ~ <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">error</p> ~ 省略 ~ </form>
上記について。
th:if="${#fields.hasErrors('name')}"
user
オブジェクトのname
フィールドにエラーが存在するか
th:errors="*{name}"
name
フィールドのエラーを表示する
Thymeleafがオブジェクトのプロパティにアクセスする場合は、
getXxx
やisXxxx
のメソッドに対して、xxx
という名前に変換してアクセスするので、
アクセスするプロパティにはGetterが必要。
ex) user.name <- user.getName()
なので、Getterメソッドだけ定義してフィールドを宣言しなくてもOK。
ex)
sample.user.auth.domain.AuthUser#isCheckPassword
この辺の実装は↓
- sample.user.controller.UserController#confirm
- src/main/resources/templates/user/form.html
SpringBootを使ってみて
Springの面倒な設定がいらない。
Springのみの場合、xmlとかannotationでいろいろ設定しないといけない
最初、理解するためにSpringだけでやってみようとしたけど、設定で躓いて諦めた。。。
ライブラリを追加する場合でも、SpringBootがよしなにやってくれるのでかなり楽。
組み込みのWebサーバがある。
ビルドしたらjarが作られるので、配置先のサーバで
java -jar xxx.jar
でAPサーバが立ち上がる(!) Gradleだと、gradle bootRun
で一発(!)
Annotationつけるだけで、全部設定してくれる。
ある程度わかってくると楽になっていいけど、初めはつらいかも。。