Java Spring Boot その2
今回は 前回の記事 の解説を簡単にしようと思います。
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @EnableAutoConfiguration public class SampleController { @RequestMapping("/") @ResponseBody String home() { return "Hello Spring Boot!"; } public static void main(String[] args) { SpringApplication.run(SampleController.class, args); } }
@Controller
コントローラを表すアノテーション
@EnableAutoConfiguration
Spring Boot の重要なアノテーション。このアノテーション 1 つで色々な設定を自動で行ってくれる。
XML 等の設定ファイル不要で様々な設定をしてくれるところが有難い。
@RequestMapping
リクエストをメソッドにマッピングするためのアノテーション
上記例でいうと "/" というリクエストあった場合、 home メソッドが呼ばれる。
@ResponseBody
Web のレスポンスボディに値をバインドするためのアノテーション
今回は簡単にこんなところで。
Java Spring Boot
今回は Spring Boot の記事を書こうと思います。
開発メモという形で何回かに分けて上げていこうと思います。
まずは Spring Boot のセットアップから
開発環境
- MacBook Air OS X Yosemite 10.10.5 ( El Capitan に上げないと )
- Java JDK 1.8.0_60
- Gradle 2.7
- Eclipse Mars Release (4.5.0)
セットアップ
Gradle ファイルの作成、Java プロジェクトのディレクトリ構成作成
$ mkdir hello_boot $ cd hello_boot $ gradle init --type java-library # 不要なファイル削除 $ rm src/main/java/Library.java $ rm src/test/java/LibraryTest.java
Spring Boot 用の設定に修正
buildscript { repositories { jcenter() } dependencies { classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE' } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'spring-boot' jar { baseName = 'hello_boot' version = '0.0.1-SNAPSHOT' } repositories { jcenter() } dependencies { compile 'org.springframework.boot:spring-boot-starter-web' testCompile 'org.springframework.boot:spring-boot-starter-test' }
Eclipse 設定ファイルを作成
$ gradle eclipse
サンプルアプリケーションを作成
参考:http://projects.spring.io/spring-boot/
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @EnableAutoConfiguration public class SampleController { @RequestMapping("/") @ResponseBody String home() { return "Hello Spring Boot!"; } public static void main(String[] args) { SpringApplication.run(SampleController.class, args); } }
サンプルアプリケーションを実行
$ gradle run
http://localhost:8080/ にアクセスして、Hello Spring Boot!
と表示されれば OK!
Java Spark
ブログを書く時間をうまく確保できてない mmts1007 です。
今回は Java のフレームワーク Spark について書きます。
Java Spark とは
Spark は Java の Web アプリケーションフレームワークです。
Ruby のフレームワーク Sinatra にインスパイアされたフレームワークです。
Java 8 で追加になった ラムダ式 を使うことでシンプルに記述することができます。
特徴
特徴としては前述のとおり
です。
サンプル
Hello Spark
とてもシンプルな例です
ルーティング
Sinatra は HTTP メソッドと URLを元にルーティングを決定します。
Spark は Sinatra にインスパイアされたため、Spark も同様にHTTP メソッドと URLを元にルーティングを決定します。
上記の例だと HTTP メソッド:GET、URL:"/" にリクエストした場合、上記のメソッドが実行されることになります。
シンプルな処理内容の記述
Spark はラムダ式を使用することで、シンプルに記述することができます。
get("URLパス", "処理内容");
となっており、第 2 引数にラムダ式を渡すことができます。
これにより、実際の処理内容をシンプルに記述することが可能となりました。
組み込みサーバ
今までの Web アプリケーションは war ファイルを作成し、それを Tomcat などのアプリケーションサーバにデプロイするのが主流でしたが今は組み込みサーバが流行っています。
サーバが組み込まれていると java -jar xxxx.jar
のように Java コマンドで実行するだけでサーバが起動します。
アプリケーションサーバを用意しなくとも Web アプリケーションが実行できるのはとても楽です。
Rest API
REST API のサンプルとしてタスクの取得/登録/更新/削除のソースの書き方のイメージです。
public class TaskSpark { public static void main(String[] args) { get("/tasks", (req, res) -> { // 1. タスク内容を全て戻す }); get("/tasks/:id", (req, res) -> { // 2. id に指定されたタスクを戻す }); post("/tasks", (req, res) -> { // 3. パラメータに指定された内容でタスクを作成する }); put("/tasks/:id", (req, res) -> { // 4. パラメータに指定された内容で id のタスクを更新する }); delete("/tasks/:id", (req, res) -> { // 5. id に指定されたタスクを削除する }); } }
Sinatra ライクな記述のため、どのようなルーティングなのか分かりやすいです。
get の /tasks のリクエストがきたら 1. が実行される といった形です。
上記のソースのように REST API のような HTTP のメソッドに意味を持たせる場合、分かりやすいフレームワークだと思います。
実際に処理を書いたサンプルが下記のとおりです。
※ DB 処理を書くのが面倒だったので、適当にメモリに保持。ここら辺の記述は適当ですw
new JsonTransformer()
を 引数に与えることで、戻りの型を変換することができます。これは Spark の機能です。
今回は JSON 型に変換したかったので JsonTransformer
クラスを作成し、指定しています。
まとめ
Sinatra ライクな Spark についての紹介でした。
といった Spark の特徴が少しでも分かって頂ければと思います。
Seasar サポート終了
2日に1回書くのがこんなに辛いとは…w もう少し頑張りますw
2015.09.26 に Seasar Conference 2015 が開催されました。
Seasar Conference 2015 | September 26, 2015 @ Hosei University
その中で、Seasar サポート終了 が発表されました。
Seasar 2 を使った開発を 2年位経験していた私にとっては、ビックニュースでした。
本気で次のフレームワークを探さなきゃなと思いました。
と言うことで、移行先に考えているフレームワークを紹介していこうと思います。
(あくまで私の好み、興味です。)
Spring Boot
http://projects.spring.io/spring-boot/
去年の JJUG CCC で知ったフレームワークです。 そこから興味を持ち、JJUG Night Seminer 等に参加しました。
【東京】JJUG ナイト・セミナー「中上級者向け!Spring Bootハンズオン!」3/25(水)開催 | 日本Javaユーザーグループ
本も持ってます!(著者のサイン入り!)
http://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AESpring-Boot%E2%80%95%E3%80%8CSpring-Framework%E3%80%8D%E3%81%A7%E7%B0%A1%E5%8D%98Java%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA-I%E3%83%BBO-BOOKS/dp/4777518655www.amazon.co.jp
Spark
Sinatra Like なフレームワークです。
Sinatra が好きな私にとっては嬉しいフレームワークでした。
HTTP のメソッドと Java のメソッドがマッピングされているので、
Resutful API を作るときにはわかりやすいと思います。
LastaFlute
LastaFlute (Javaでリーンスタートアップ) | DBFlute
Seasar Conference 2015 で発表されたフレームワークです。
Seasar を Java 8 でフォークしたフレームワークとのことです。
( LastaFlute 早く触りたい。早く週末になれ!※まだ月曜日 )
それぞれのフレームワークの詳細については個別に書いていこうと思います。
次の記述でまずは Spark について書こうと思います。
Java Stream API
前回の記事に引き続き Java に関して。
この記事読んでくださった前提で記事を書きます。 mmts1007.hatenablog.jp
Java Stream API
コレクション(List, Map 等) に対する要素の関数型の操作をサポートするクラスです
関数型というのが、ラムダ式のことだと思ってください。
Stream とは
Stream は大きく 3 つの操作から成り立っています。
具体的にはソース、中間操作、終端操作です。
ソース
コレクション(List, Map) からストリームを生成するための処理です。
中間操作
ストリームの要素を加工、変換、ソートするための処理です。
終端操作
ストリームを完了させるための処理です。 例として、ストリームの要素を集約、カウントします。
サンプルソース
代表的なメソッド
ソース
stream
コレクション(List, Map) からストリームを生成するためのメソッドです。
中間操作
map
mapping の略(おそらく)で、ラムダ式で指定された処理方法で要素の型変換を行ったストリームを返却します。 私は A クラスから B クラスにマッピングすると覚えています。filter
ラムダ式で指定した条件がtrue
になるオブジェクトのみ抽出したストリームを返却します。distinct
重複を除いたストリームを返却します。sorted
ソートを行ったストリームを返却します。
終端操作
forEach
コレクションの各要素に対してラムダ式で指定した処理を行う場合に使用します。count
ストリームの要素の個数をカウントします。collect
ラムダ式に指定した方法でストリームの要素を集約します。
ラムダ式 x Stream API
すでにお分りかもしれませんが、 Stream APIにはラムダ式が必須になります。
例えば filter
メソッドはフィルタリングの条件を渡すだけで、フィルタリングを行ってくれます。
開発者はフィルタリングの方法を全て実装する必要は無くなります。条件の実装に集中して行えば良いのです。
ラムダ式は Stream API のような場合に強力な力を発揮します。
Stream API の利点
直感的なコーディング
サンプルソースの最後に記載しましたが、
Stream API は日本語的に流れるように記述することができ、とても直感的です。
例えば、 従業員リストから 年齢が 30 歳以下でかつ、住所が東京なデータを取得する 場合は
employeeList.stream() .filter(employee -> employee.age <= 30) // 年齢が 30 歳以下で .filter(employee -> employee.address == "東京") // 住所が "東京" .forEach(System.out::println);
と日本語をそのままメソッドにマッピングしたように記述することができます。
並列処理が容易
Stream API は内部イテレータのため、並列処理を容易に行えます。
並列処理を行う場合は、ストリームに対して parallel
メソッドを使用することで並列に処理することができます。
今回はここまで。
Java のラムダ式
何書くか悩みましたが、今回は Java 8 で導入されたラムダ式について
今更!? って思われるかもしれませんが、
私自身理解するのに苦労したので、まとめるという意味で書きます。
ラムダ式とは
ラムダ式をとっても簡単に説明すると
メソッドの引数に処理を渡すための構文だと思ってください。
ラムダ式のサンプル
ラムダ式で書かれている部分は下記のとおりです https://gist.github.com/mmts1007/a37e6fba2aafde4cf230#file-hellolambda-java-L17-L19
さらにフォーマットを修正すると下記のとおりです。
(String name) -> { System.out.println(name); }
ラムダ式は下記のように記述をします。
( 処理に渡す引数 ) -> { 処理内容 }
これより names.stream().forEach((String name) -> { System.out.println(name); }); )
の処理は
forEach
によって得られた 1 つの要素を name
という変数として定義し、処理内容 ( System.out.println
) に渡す
ということを行っています。
よって names
の各要素が 1 つずつ標準出力に出力されます。
利用場面
今はラムダ式のメリットが分かりにくいと思いますが、
次の記事に書く Stream API について触れれば、
ラムダ式のメリットが分かると思いますのでそちらで。