Serving Web Content with Spring MVC

f:id:Naotsugu:20150110034558p:plain

このガイドでは Spting による"hello world" Web サイトを作っていきます。

What you’ll need

How to complete this guide

以下から雛形をダウンロードできます。

git clone https://github.com/spring-guides/gs-serving-web-content.git

が、ここではスクラッチで Gradle 使って進めることにします。

Build with Gradle

プロジェクト用のディレクトリを用意して、その中にソースディレクトリ作成します。

mkdir -p src/main/java/hello

build.gradle 作成していきます。

touch build.gradle

内容は以下。

buildscript {
    repositories {
        maven { url "https://repo.spring.io/libs-release" }
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.10.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot'

jar {
    baseName = 'gs-serving-web-content'
    version =  '0.1.0'
}

repositories {
    mavenLocal()
    mavenCentral()
    maven { url "https://repo.spring.io/libs-release" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-thymeleaf")
    testCompile("junit:junit")
}

task wrapper(type: Wrapper) {
    gradleVersion = '1.11'
}

spring-boot-gradle-plugin が以下の面倒を見てくれます。

  • 必要な jar あつめて fat-jar を作る
  • main メソッド見つけてjar のマニフェストに自動的に書いて実行可能jarにする
  • Spring Boot の依存を(書き換えることもできるけど)勝手に設定する

Create a web controller

Spring によるWebサイト構築のアプローチでは、リクエストをコントローラで扱います。 コントローラには単に @Controller アノテーションを付ければよいです。

以下の例では GreetingController が GET リクエストを受け、名前(ここでは "greeting")により View を返却します。 View の責務は HTML コンテンツのレンダリングです。

クラスファイルを作成し、

touch src/main/java/hello/GreetingController.java

以下のようにします。

package hello;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class GreetingController {

    @RequestMapping("/greeting")
    public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
        model.addAttribute("name", name);
        return "greeting";
    }

}

コントローラはとてもシンプルですがこれで十分です。順に細かくみていきましょう。

@RequestMapping アンテーションにより /greeting へのHTTPリクエストが greeting() メソッドマッピングされます。

この例ではPUTやPOSTなどを扱っていません。@RequestMapping はデフォルトで全てのHTTPメソッドを受けつけます。 個別に指定したい場合は @RequestMapping(method=GET) のようにします。

@RequestParamname パラメータとして受けたクエリ文字列をgreeting()メソッドの引数値としてバインドします。 リクエストパラメータは任意値なので、defaultValue としてデフォルト値を定義しています。

メソッド内の実装は view テクノロジに頼っており、この例では サーバサイドでの HTML のレンダリングに Thymeleaf を使用しています。 Thymeleaf は以下のような greeting.html テンプレートをパースして、コントローラにより設定された ${name} パラメータを th:text 式の値として評価します。

greeting.html ファイルを作成します。

mkdir -p src/main/resources/templates/
touch src/main/resources/templates/greeting.html

中身は以下となります。

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Getting Started: Serving Web Content</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
    <p th:text="'Hello, ' + ${name} + '!'" />
</body>
</html>

Make the application executable

外部のアプリケーションサーバにデプロイするために、伝統的な WAR としてサービスをパッケージすることもできますが、ここではスタンドアロンアプリケーションを作成するアプローチで進めます。

古き良き Java main() メソッドで起動できる全部入りのの実行可能 JAR へパッケージします。 Spring がサポートする組み込みの Tomcat サーバを HTTP ランタイムとして使うことで、外部インスタンスへのデプロイ無くアプリケーションが実行できるようになります。

Application クラスを作成します。

touch src/main/java/hello/Application.java

Application クラスは以下のようになります。

package hello;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

main() メソッドでは SpringApplication ヘルパークラスの run() メソッドへ Application.class を渡しています。これにより Spring は Application のアノテーション定義を読み込み、Spring アプリケーションコンテキストのコンポーネントとして管理します。

@ComponentScan アノテーションは 直接的または間接的に @Component でマークされているクラスを hello パッケージを再帰的に検索するような指示です。 この指示により Spring は GreetingController をコンポーネントとして登録します(@Controller@Component の一種なので)。

@EnableAutoConfiguration アノテーションはクラスパスに基づいて合理的なデフォルトの振る舞いを設定します。 例えばアプリケーションが組み込みバージョンの Tomcat (tomcat-embed-core.jar) に依存していれば、あなたに代わって合理的なデフォルト設定が設定されます。 Spring MVC (spring-webmvc.jar) に依存していれば、Spring MVC DispatcherServlet が設定されて登録されます(web.xml は不要です)。 この自動設定の仕組みは柔軟で強力です。

Build an executable JAR

Gradle を使っているなら、アプリケーションの実行は ./gradlew bootRun とするだけです。

実行可能 jar を作成するには以下のようにし(初回のみgradle wrapperが必要)、

./gradlew build

jar を実行すればアプリケーションが起動します。

java -jar build/libs/gs-serving-web-content-0.1.0.jar

ここではJARを作成しました。 WAR を作成するには、Getting Started · Converting a Spring Boot JAR Application to a WAR を参照してください。

Test the service

それでは http://localhost:8080/greeting にアクセスしてみましょう。

f:id:Naotsugu:20150112001820p:plain

クエリ文字付きでもアクセスしてみましょう。http://localhost:8080/greeting?name=User

f:id:Naotsugu:20150112001925p:plain