mmts1007’s diary

プログラミング関連の技術系ブログです。

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 のセットアップから

開発環境

セットアップ

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 用の設定に修正

参考: http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#getting-started-gradle-installation

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

とてもシンプルな例です

gistb99122ff8af2fa0774e4

ルーティング

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

gist247abdc95d81b72bbfaa

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

sparkjava.com

Sinatra Like なフレームワークです。
Sinatra が好きな私にとっては嬉しいフレームワークでした。

HTTP のメソッドJavaメソッドマッピングされているので、
Resutful API を作るときにはわかりやすいと思います。

LastaFlute

LastaFlute (Javaでリーンスタートアップ) | DBFlute

speakerdeck.com

Seasar Conference 2015 で発表されたフレームワークです。
SeasarJava 8 でフォークしたフレームワークとのことです。
( LastaFlute 早く触りたい。早く週末になれ!※まだ月曜日 )

それぞれのフレームワークの詳細については個別に書いていこうと思います。
次の記述でまずは Spark について書こうと思います。

Java Stream API

前回の記事に引き続き Java に関して。

この記事読んでくださった前提で記事を書きます。 mmts1007.hatenablog.jp

Java Stream API

コレクション(List, Map 等) に対する要素の関数型の操作をサポートするクラスです
関数型というのが、ラムダ式のことだと思ってください。

Stream とは

Stream は大きく 3 つの操作から成り立っています。
具体的にはソース中間操作終端操作です。

ソース

コレクション(List, Map) からストリームを生成するための処理です。

中間操作

ストリームの要素を加工、変換、ソートするための処理です。

終端操作

ストリームを完了させるための処理です。 例として、ストリームの要素を集約、カウントします。

サンプルソース

gist6c1daf62d8fd167ae98c

代表的なメソッド

ソース

  • 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 で導入されたラムダ式について

今更!? って思われるかもしれませんが、
私自身理解するのに苦労したので、まとめるという意味で書きます。

ラムダ式とは

ラムダ式をとっても簡単に説明すると
メソッドの引数に処理を渡すための構文だと思ってください。

ラムダ式のサンプル

gista37e6fba2aafde4cf230

ラムダ式で書かれている部分は下記のとおりです 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 について触れれば、
ラムダ式のメリットが分かると思いますのでそちらで。