【社内用】Spring Bootのプロジェクトにアサインされた方へ（作成中）


Spring Bootに初めてアサインされた社員に向けた方へ、説明する際に使うアジェンダです。

# 前提知識
* Java8の基本構文
* HTML5, CSS3, JavaScript(ES5)
* Servlet3.1
* HTTPのGET, POST

## 開発環境
* Eclipse Pleiades 4.7
* Java8
* Spring Boot 1.5.10
* PostgreSQL 9.6
* superagent.js


# 目標
以下のことができるようになることを目指す。

* 画面の追加
* クライアント-サーバ間の処理の追加（Restful APIの追加）
* DBにアクセス（MyBatis）
* 各ファイルの理解
* MVCに対応するController, Serviceなどの理解
* Mavenでjarを作成し、デプロイ
* Mavenからライブラリの追加
* アクセス権限処理の追加（Spring Security）
* 設定より規約の考えの理解



# ライブラリの説明

## Spring Boot
* 数あるSpring関係のライブラリをまとめたもの
* 最小構成でHelloWorldが表示できる
    - あらかじめログの設定など、必要な設定がなされている
* 流行ってきている？


## MyBatis
* O/R Mapper. iBatisのバージョンアップ版
* XMLだけでなく、アノテーションでもSQLを記述することができる


## Thymeleaf
* テンプレートエンジン。JSPのようなもの。
* JSPがJSP専用のタグを指定しているのに対して、ThymeleafはThymeleaf専用の属性で指定する。
    - ブラウザは認識できない属性を無視するだけなので、レイアウトが崩れない？
	- デザイナとプログラマで分業できる
* Spring BootはJSPでなくThymeleafを推奨している

## Mavenとは
[
【超初心者向け】Maven超入門](https://qiita.com/tarosa0001/items/e5667cfa857529900216#maven%E3%81%A8%E3%81%AF)

* ビルド管理ツール
* `pom.xml`に設定する
* `<dependency>`で外部ライブラリを利用できる。


# 具体的な説明

## 1. フォルダ構成の説明

## SpringとMVC
* Controller
* Service
* Model
* View

## 1. 画面の追加

### 手順
1. `src/main/static/template`フォルダにHTMLを配置する
2. Controllerクラスに、作成したHTMLを返すメソッドを作成する

```java:SampleController.java
public ModelAndView index(ModelAndView mav) {
    mav.setViewName("sample");
    return mav;
}
```

### ポイント
* `setViewName`に渡すVIEW名は拡張子不要（拡張子があっても問題ない）。JSPとThymeleafどちらでも使えるようにするためらしい。
* 
* 


## 2. Restful APIの追加

### POST API
* superagentでは`post`, `send`メソッドを使う

### POST API（ファイルアップロード）
* superagentでは`post`, `field`, ...メソッドを使う

### Restful API
https://qiita.com/TakahiRoyte/items/949f4e88caecb02119aa
* APIの命名規則
* GETとPOSTの使い分け


## 3. MyBatisでDBにアクセス
[MyBatis公式サイト](http://www.mybatis.org/mybatis-3/ja/)

### XML
* mybatis-config.xml
* `src/main/resources/mybatis/mapper/*.xml`
* タグを使ってSQLを動的に生成できる
    - `<if>`, `<foreach>`, `<where>`など
* MyBatisが受け取る情報を推測するので、`parameterType`属性はたぶん不要。

### DAOクラス
* `@Component`を付与する
* `sqlSession`の`selectOne`や`selectList`などのメソッドを呼ぶ


## 4. Spring Security
[Spring Security Reference](https://docs.spring.io/spring-security/site/docs/5.0.4.BUILD-SNAPSHOT/reference/htmlsingle/)
[Thymeleaf + Spring Security integration basics](https://www.thymeleaf.org/doc/articles/springsecurity.html)

### `SecurityConfig.java`

以下の項目などを設定する

* ログインしなくてもアクセスできるURL
* ロールがないと、アクセスできないURL

### Thymeleaf
* `sec:authorize="hasRole('ROLE_USER')"`のような記述ができる


## 5. Mavenの使い方

### 既存システムでの設定
* Spring Boot用の`pom.xml`（spring-boot-starter-parent）を`<parent>`で指定している
    - 利用する外部ライブラリのバージョンも定義されている。
    - バージョンを指定したい場合は、`<properties>`で指定する。
* 自社ライブラリの利用
* JavaDocの生成

### EclipseでMaven更新
`pom.xml`を修正したら、「プロジェクトを右クリック ＞ Maven ＞ プロジェクトの更新」で更新する。

### jarファイルの生成（デプロイ用）
* `mvn install`コマンドを実行すると、jarファイルが`プロジェクト配下/target`フォルダに生成される。
* テストコードの実行をスキップする場合は、`mvn install -Dmaven.test.skip=true`を実行する。


## 6. Spring Boot関係

### application.properties
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

* Spring Boot用の外部設定値を定義するファイル
* Eclipseの「Springプロパティエディタ」で開くと、キーに対して入力補完できる。
* javaコマンドの引数で指定することも可能。`java -jar sample.jar --server.port=8081`
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html


### Profile
https://area-b.com/blog/2015/01/30/2316/
http://endok.hatenablog.com/entry/2016/06/12/181900
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html

* 実行環境ごとに設定値などを切り替える仕組み。
* Javaのクラスに対して`@Profile("test")`などで切り替えられる
* Thymeleafでは`@environment`を使って切り替える
https://blog.tagbangers.co.jp/ja/2015/01/18/thymeleaf-environment-properties

### 既存システムでの設定
* 既存システムでは3種類のプロファイルを定義する
    - local: ローカル環境で起動
    - test: 開発環境のサーバで起動
    - release: 本番環境のサーバで起動

* javaコマンドの引数で`--spring.profiles.active=local`のようにプロファイルを指定

* 各プロファイルに対応した`application.properties`を用意している
    - `application.properties` : デフォルトの設定値。
    - `application-test.properties` : テスト環境用の設定値。
    - `application-release.properties`: 本番環境用の設定値。Swaggerなどのツールの無効化、キャッシュの有効化
    - `application-local.properties` : 個人用の設定。コミットしないこと前提。


## デプロイ方法
1. コマンドで`mvn install -Dmaven.test.skip=true`を実行して、jarファイルを生成する
    * `プロジェクト配下/target`フォルダに生成される
2. javaコマンドでサーバを起動する
    * 起動用のバッチファイルあり（start.bat)


## 既存プロジェクトのログ設定
* SLF4J（インターフェイス）とLogback（実装）の組み合わせを採用した
    - 古いシステムだと、commons-logging（インターフェイス）とlog4j（実装）の組み合わせが多い
* `src/main/resources/logbakc.xml`
    - 最初から用意されているログフォーマットに、個別の設定を追記
* Lombokの`@Slf4j`でフィールド`log`を生成
* 実行したSQL（プリペアドの値も出力された状態）をログに出力するため、log4jdbcを採用した
    - https://qiita.com/YAKINIKU/items/5141c7205f3c67691c92
* Cntrollerの前後でログを出力（AOP）


## JUnit

## Springの@autowired




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



# 実習課題

## 前提条件
* 開発環境が整っている
* Spring Bootを使った既存プロジェクトに対して、機能を追加する
* Ajax通信は、superaget.jsを利用する


## データベース

```sql:create_table.sql
CREATE table user (
  SERIAL user_id NOT NULL,
  TEXT user_name NOT NULL,
  TEXT section NOT NULL,
  PRIMARY KEY (user_id)
);
```

## Controllerクラスの追加
* ブラウザの開発ツールで、Request/Responseを確認すること

### HTMLファイルの作成
`sample.html`を作成して、URL`/sample.html`で`sample.html`の中身を表示

* メッセージファイル（`message.properties`）の値を参照する

### GET APIを作成（パラメータは1個）
* `@RequestParam`で、クライアントから数値を1個受け取る。
* サーバ側で、受け取った数値の2乗を計算して、クライアントに返す

### GET APIを作成（1個の情報を渡す）
* `@RequestParam`で、クライアントから数値を1個受け取る。
* サーバ側で、受け取った数値の2乗を計算して、クライアントに返す

### GET APIを作成（複数の情報を渡す）
* Beanクラスを作成して、そのクラスで複数の情報を受け取る。
* サーバ側で、受け取った情報に何らかの処理を行い、クライアントに返す

### POST APIを作成
* POST APIを作成する。
    - 複数の情報を受け取る
    - 受け取った情報に対して何らかの処理を行い、クライアントに返す
* JavaScriptで作成したAPIを呼び出す
    - レスポンスの内容を画面に表示する

### POST APIを作成（ファイルアップロード）
* POST APIを作成する
    - 1個のファイルと、1個の文字列を受け取る
    - 受け取ったファイルを保存する
* JavaScriptで作成したAPIを呼び出す


## データベースへのアクセス
* DAOクラスにメソッドを追加
* Controllerクラス内のメソッドから、DAOクラスのメソッドを呼び出す


### `user_id`でSELECT
* DAOクラスにメソッドを作成する
    - `user_id`で絞り込んだ結果を取得するメソッド

### ユーザ名 or 部署でSELECT
* `<if>`, `<where>`を使って、WHERE句を記述
* SQLに渡す情報がnullならば、絞り込まないこと


### `user`テーブルにINSERT
* `<if>`, `<where>`を使って、WHERE句を記述
* SQLに渡す情報がnullならば、絞り込まないこと

### 1回のSELECT文で階層構造のクラスに情報を格納
* `<collection>`を使って、SQL文を記述


## Maven
### `pom.xml`を修正して、外部ライブラリを利用する
* Mavenローカルリポジトリを確認
* Eclipseのプロジェクトプロパティで確認

### jarファイルを生成して、javaコマンドでサーバを起動
* Eclipseを使わずに、mvnコマンドでjarファイルを生成
* javaコマンドの引数でポート番号を指定
* プロファイルを変更して、設定値などが切り替わることを確認

### ログの確認
* logback.xmlでログレベルを変更して、ログの出力される/されないを確認


## 文章問題
### HTTP
* HTTPのGETとPOSTの違いを説明しなさい。
    -リクエスト/レスポンスのヘッダとボディ

### データベース
* O/R Mapperの特徴を、メリット,デメリットをふまえて説明しなさい
* Javaから情報を受け取るには、`#` or `$`が利用できる。その違いを説明しなさい。

## HelloWorld

## RestfulAPIの追加

## @RequestBody, @RequestParamなど

## ファイルアップロード

## MyBatisの導入

## Spring Boot 徹底入門 14章のサンプルWebシステム

## Servletの課題






# 【補足】Terasolunaとの比較