はじめに
この記事は社内でSpring Boot(実質的にはSpring?)の勉強会を行うにあたり作成した資料となります。
1時間程度で済む簡単なものになっています。
「Spring Bootってこんな感じなんだ」ということが少しでも伝われば幸いです。
なお、私自身Spring並びにSpring Boot初心者なため、記事に誤っている点があるかもしれません。
その際はご指摘いただけますと幸いです。
環境
- Mac
- Spring 2.0.2
- Dokcer for Mac
- Gradle 5.2.1
- VSCode
※Eclipseでええやん!って人はDockerじゃなくても○。
※Gradleについては以下の記事が分かり易かったです。
→ [多分わかりやすいGradle入門] (https://tech-lab.sios.jp/archives/9500)
[Gradle入門] (https://qiita.com/vvakame/items/83366fbfa47562fafbf4)
Springについて
強み
- 変更に強い
- DI(Dependency Injection)という仕組みが導入されている。
- それぞれが独立しているため依存度が低く、変更に強い。
- DI(Dependency Injection)という仕組みが導入されている。
- 拡張性が高い
- 基本的な機能の大部分が
インターフェース
として提供されている。 - 必要な部分は簡単に追加できる。
- 基本的な機能の大部分が
- 保守性が高い
-
AOP(アスペクト指向プログラミング)
を用いることができる。- 共通のプログラムを再利用することでコーディング量減・修正も簡単
-
- テストが簡単
-
Spring MVC Test
という専用のテストプログラムで結合テストが簡単にできる。
-
- 大規模データベース
NoSQL
に対応
弱み
- フレームワークの規模が大きく、全体を把握するのが難しい。
- DIコンテナの正しい使い方が難しい
- 日本語のドキュメントが乏しい
じゃあSpring Bootって何?
WEBアプリケーションに特化した「Spring MVC」というフレームワークの完成形として、Spring MVCやその他のSpring Frameworkのライブラリ類をいい感じに組み合わせたWebアプリケーション環境を簡単に構築するライブラリです。
【参考: [[Java] Spring BootでHello World!(入門編)] (https://www.marineroad.com/staff-blog/16785.html)】
その特徴を簡単にまとめると、
1.アノテーションを記述するだけで実装できる機能が多数あり、コード量を削減できる
2.Webコンテナをjarに内蔵することで、jar単体でWebアプリケーションが実行できる
3.今までのSpringフレームワークでは必須だった、XML設定ファイルが不要になった
4.Spring Initializrというプロジェクト雛形生成サービスがあり、一から開発する必要がない
などなど様々な高速システム開発のための機能が提供されています。
【[[Java] Spring Bootで簡単・高速にWebAPI開発] (http://www.xn--springboot-mh5yz04y.tokyo/01-introduction-spring-boot/)】
下準備
- Docker for Macをインストールし、
docker
コマンドが打てることを確認する。 - 以下のコマンドを実行する。
$ git clone https://github.com/miwa0519/spring-boot.git
$ cd spring-boot/spring_boot_docker/
- 以下のコマンドを実行。
- Tomcatが8080ポートで動く。
- 3000番ポートは人気者だから別ポートがいい、という場合は
docker-compose.yml
内の3000部分を別の番号に変えるといい。 - Springが上手く動いていればコンソールに
Spring>>>
みたいな例のAAが出る。出ると少しテンションが上がる。
$ docker build -t spring-docker ./
$ docker run -p 3000:8080 spring-docker
-
http://localhost:3000
にアクセスする。(3000は任意のポートに変えていい)
今回のサンプルだと、ソースコードを編集する度に上記コマンドを実行する必要があります。
今後改善予定です。面倒臭くてすみません
- ※こちらは必要な人のみ
- [こちらの記事] (https://qiita.com/h-r-k-matsumoto/items/406a3b48f75131a65e0a) でVSCode向けのプラグインを取り纏めてくださっています。
import
とか手入力してられるかよ!という人にはオススメです。
とりあえずHello Worldしてみる
src/main/java/com/example/demo
直下に HelloController.java
を作成します。
HelloController.java
内に以下のソースを記述します。
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello World!";
}
}
http://localhost:3000/hello
にアクセスすると Hello World!
と表示されていると思います。
アノテーションが二つ出てきました。これらが何をしているかを簡単に説明します。
-
@RestController
:RestControllerアノテーションをつけると、このコントローラーがWebアプリケーション
のリクエストを受け付けるRestコントローラー
になる。 -
@RequestMapping
:RequestMappingアノテーションをつけると、ルーティングを行なってくれる。今回でいうと、http://localhost:3000/hello
にアクセスするとHello
メソッドを実行する、という紐付けが行われる。
これらが使えるように、それぞれのクラスをインポートしてます。インポート出来ていないとコンパイルエラーになるので気をつけてください。
もう少しWebアプリらしく Hello World!
したいので、今度はテンプレートを作ってみたいと思います。
Viewの部分を実装する
Spring Bootでは1.2以降はJSPが非推奨とされています。
なので今回は Thymeleaf
というテンプレートエンジンを使います。
Spring Bootでは Thymeleaf
を使うのが無難らしいです。
Thymeleafを使えるように設定する
設定をしないとThymeleafは使えません。
build.gradle
を以下のように書き換えてください。
// 中略
dependencies {
+ compile('org.springframework.boot:spring-boot-starter-thymeleaf')
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
実際にHTMLを書いてみる
Thymeleafの設定ができたので、実際にHTMLを書いてViewを実装していきます。
src/resources
直下に templates
ディレクトリを用意し、 hello.html
ファイルを作成します。
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'Hello Wonderful World!'" />
</body>
</html>
※ th:text
は Thymeleaf
の属性。Thymeleafの記述については以下が分かりやすかったです。
[[Java] Spring BootでThymeleafを使ってみよう!(応用編)] (https://www.marineroad.com/staff-blog/17761.html)
HelloControllerを修正する
テンプレートを用意したので、今度はコントローラーがそのテンプレートを呼び出してくれるように修正します。
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
+ import org.springframework.stereotype.Controller;
+ import org.springframework.web.bind.annotation.RequestMethod;
- @RestController
+ @Controller
public class HelloController {
@RequestMapping("/hello")
public String hello() {
- return "Hello World!"
+ return "hello";
}
}
@RestController
を @Controller
に変更しました。
これにより、WebAPIとして機能していた HelloController
が MVC
の C
として振る舞うようになります。
それにより、 return
の部分に記載した hello
を ViewResolver
がView名として認識し、実際のファイル名に変換し、クライアントに返却します。
最初のコマンドを再度実行した後に
http://localhost:3000/hello
をリロードします。テンプレートが呼び出されて、表示される文言が変わっていることが確認できると思います。
簡単な計算アプリを作ってみる
MVCのVとCについてはここまでで学ぶことが出来ました。
最後にModelについての説明を加えながら、与えた数字を元に足し算を行ってくれる簡単なアプリを作成したいと思います。
Model作ってみる
まず、フォームの値を受け取って計算するためのモデルを作成します。
Controllerを作成したディレクトリの中に model
ディレクトリを作成し、その中に Form.java
を作成します。
package com.example.demo.model;
public class Form {
private int num1 = 0;
private int num2 = 0;
private int total = 0;
public int getNum1(){
return num1;
}
public void setNum1(int num){
this.num1 = num;
}
public int getNum2(){
return num2;
}
public void setNum2(int num){
this.num2 = num;
}
public int getTotal(){
return total;
}
public void setTotal(int total){
this.total = total;
}
public void sumTotal(){
total = this.num1 + this.num2;
setTotal(total);
}
}
入力値を保持する num1
、 num2
と合計値を保持する total
フィールドを作成し、それぞれに getter
と setter
を定義します。
また、 num1
と num2
の合計を算出する sumTotal
メソッドを定義しておきます。
入力フォームを表示する
modelを定義したので、次は入力フォームを表示してみます。
まず、入力フォームを表示するためのコントローラーを定義します。
package com.example.demo;
import com.example.demo.model.Form;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@Controller
public class CalculateController {
@RequestMapping("/calculate")
public String form(Model model){
model.addAttribute("form", new Form());
return "index";
}
}
今までの Controller
と違うところは、メソッドに Model
型のオブジェクトを引数に取っているところです。
この Model
に値をセットすることでHTMLに値を渡す事が出来ます。(Springが用意してくれているクラス)
model.addAttribute("form", new Form())
の部分で、 model
に対し、Formインスタンスを渡しています。
model.addAttribute("変数名", オブジェクト)
※ちなみに、第2引数に Form form
と記述しても同じ意味になります。(裏で
addAttribute
と同じことが実行されるイメージ)
【参考:[【Spring Boot】ModelクラスとModel And Viewクラス] (https://pointsandlines.jp/java/model-and-view)】
form
メソッドでは index
というテンプレートを最後に返しています。
今度は index
テンプレートを作成し、入力画面を作成します。
入力画面を作る
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Index</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Form</h1>
<form action="#" th:action="@{/result}" th:object="${form}" method="post">
<p>first number: <input type="number" th:field="*{num1}" /></p>
<p>Second number: <input type="number" th:field="*{num2}" /></p>
<p><input type="submit" value="calculate" /></p>
</form>
</body>
</html>
最初に作った hello.html
と異なるところは、 th:action
、 th:object
、 th:field
という属性が出てきている点です。
なんとなく見た目で伝わるかと思いますが、簡単に使い方だけご紹介します。
th:action | th:object | th:field="*{フィールド名}" |
---|---|---|
フォームのアクションを指定する | ${}で指定したオブジェクトにフォームで入力した値が入る。 | th:objectで指定しているオブジェクトのフィールドに対して入力された値を入れる。 |
【参考: [Spring Boot でフォームの値を取得して操作] 】(https://qiita.com/NariseT/items/172ca093364aa9391989)
各テキストエリアに入力された値は、先ほどコントローラーで Model
オブジェクトに追加した Form
インスタンスの各フィールドに値がセットされます。
http://localhost:3000/calculate
にアクセスすると入力フォームが表示されるはずです。
Controllerを修正する
今度はフォームで入力した値を受け取り、計算を行い、その結果を画面に表示できるようにします。
まずはコントローラーに新しいメソッドを追加します。
package com.example.demo;
import com.example.demo.model.Form;
// 中略
import org.springframework.ui.Model;
+ import org.springframework.web.bind.annotation.RequestMethod;
+ import org.springframework.web.bind.annotation.ModelAttribute;
@Controller
public class CalculateController {
@RequestMapping("/calculate")
public String form(Model model){
model.addAttribute("form", new Form());
return "index";
}
+ @RequestMapping(value="/result", method = RequestMethod.POST)
+ public String result(@ModelAttribute Form form, Model model){
+ form.sumTotal();
+ model.addAttribute("form", form);
+ return "result";
+ }
}
@RequsetMapping
は今回パラメータを受け取るので、HTTPメソッドを指定します。
method = RequestMethod.post
と記載することでこれはPOSTだよ!と指定できます。
また今回はメソッドの引数に @ModelAttribute
というアノテーションがついています。このアノテーションをつけると input
の値を受け取ることが出来ます。
form
の各フィールドには入力フォームで入力された値がセットされている状態なので、 Form
クラスで定義した sumTotal
メソッドを呼び出し、 form
の total
フィールドに合計値を保持させます。
その結果を result
テンプレートに表示させたいので、今度は result
テンプレートを作成します。
計算結果を画面に表示する
templates
ディレクトリ直下に以下のファイルを作成してください。
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Result</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<h1>Result</h1>
<p th:text="'Answer: ' + ${form.getTotal()}" />
<a href="/calculate">Calculate Another number</a>
</body>
</html>
${}
で式展開を行なってくれるので、getterを使っての合計値を取得し、表示します。
計算実行結果は以下です。
最後に
私自身がSpring Bootについて初歩的な部分を学んで感じたのは以下の三点です。
- 面倒な設定が少なく、すぐに開発に取りかかれた。(Dockerで動かすのが大変だったくらい)
- ソースコードが割と直感的に書ける
- 自分の求めているドキュメントに辿り着くまでの時間が壮大(自分の調べ方が下手なだけかも)
とはいえ私自身、初歩的な部分しかまだ分からない状況なので、今後も少しずつ学んでいけたらと思っております。
この記事がSpring Boot、Spring初心者の何かの皆さんの役に立てば幸いです。
参考
-
Docker+Spring-boot事始め
環境構築でお世話になりました。プロジェクトを作るところからやってみたい方におすすめ - [エンジニア志望者必見のSpring Frameworkとは] (https://blog.codecamp.jp/spring-framework)
- [Spring Boot でフォームの値を取得して操作] (https://qiita.com/NariseT/items/172ca093364aa9391989) フォームってどうやって書くんだ?という時に凄く助かりました。
- [多様化するJavaのフレームワーク問題を解決する、「Spring Boot」とは?] (https://codezine.jp/article/detail/11310)