Spring BootでWARを作成して別のTomcatにデプロイする

[Spring BootのTomcatのバージョンを調べてみる](http://qiita.com/ARS_2000/items/0229ad4777876bc3011c)の冒頭でも述べた通り、Spring BootではTomcatが組み込まれており、非常に手軽に開発ができます。
ただ、開発中はSTS + Spring Bootで組み込みTomcatを使って、本番環境や結合テスト環境には別でTomcat(とかJettyとかJBossとか)を立てて、そっちで稼働させたい、なんてケースもあるかと思います。
現に自分の今の現場はそんな構成になっています。
なので、今回はSTS + Spring BootでWARを作って別のTomcatにデプロイして動作させるまでの手順を書きたいと思います。

# 前提
* 環境はもろもろ揃っているものとします。
* 以下の公式を参照しています。  
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file

# 素材となるアプリの雛形を作る
まずはデプロイするアプリの雛形を簡単に作ります。
ここでは以下のmavenコマンドでmavenプロジェクトを作ることにします。
※groupとかartifactとかは適当に、、

```
mvn -B archetype:generate -DgroupId=com.example -DartifactId=nagap -Dversion=1.0.0-SNAPSHOT -DarchetypeArtifactId=maven-archetype-quickstart
```

# Spring Bootを利用する設定をpom.xmlに記述する
ここでは以下のような感じにpom.xmlを修正します。

```pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example</groupId>
	<artifactId>nagap</artifactId>
	<packaging>war</packaging>
	<version>1.0.0-SNAPSHOT</version>
	<name>nagap</name>
	<url>http://maven.apache.org</url>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.3.0.RELEASE</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
		</dependency>
	</dependencies>

	<properties>
		<java.version>1.8</java.version>
	</properties>
</project>
```

ここで重要なのは以下2点です。

* packagingをwarにすること(当然ですね)
* spring-boot-starter-tomcatのscopeをprovidedにすること

# 超簡単に実装してみる
Appクラスを以下のような感じで超簡単に実装します。
なお、このクラスをエントリポイントとします。
※目的から逸れるためクラス構成等は気にしないことにします。

```App.java
package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class App extends SpringBootServletInitializer {

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

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(App.class);
	}
	
	@RequestMapping(value = "nagap", method = RequestMethod.GET)
	public String getSomething() {
		return "something";
	}
}
```

ここで重要なのは以下2点です。

* SpringBootServletInitializerクラスを継承すること
* configureメソッドをoverrideすること

ここでいったん動作確認をします。
プロジェクトを選択して右クリック
【Run As】→【Spring Boot App】で組み込みTomcatを起動します。
http://localhost:8080/nagap
へアクセスしブラウザ上に「something」と表示されればOKです。
ここまででSTS + Spring Bootで素材となるアプリが出来上がりです(かなり雑ですがそこはorz orz)

# WARファイルを作成する
これはpackageするだけなので簡単です。
STSでプロジェクトを選択して右クリック→
【Run As】→【6 Maven build】→Goalsに「package」を入力→【Run】ボタン押下
しばらくすると、プロジェクトルートのtargetフォルダの中にWARファイルが作成されます。
今回はnagap-1.0.0-SNAPSHOT.warという形で作成されました。

# 別のTomcatにデプロイする
本題ですがこれも簡単ですｗｗ
出来あがったwarファイルを、デプロイしたいTomcatのwebapps配下に置きます。
あとはTomcatを起動すればOKです。

# 別のTomcatにデプロイしたアプリの動作確認をする
ここで動作確認してみます。
http://localhost:8080/nagap-1.0.0-SNAPSHOT/nagap
前項と同じようにブラウザ上に「something」と表示されればOKです。
ここで重要なのは以下2点です。

* アクセスする時のコンテキスト名はwarのファイル名(ここではnagap-1.0.0-SNAPSHOT)になる
* warを作成する時のjavaのバージョンと別Tomcatが動いているjavaのバージョンが違うと404が返却されることがある←ハマりました

以上です。
web.xmlやコンテキスト定義は不要で、簡単にデプロイすることが出来ました。
恐らく肝は

* SpringBootServletInitializerクラスを継承すること
* configureメソッドをoverrideすること

あたりで、これらを守ることで内部でよしなにやってくれているのかと思います。
これはTomcatを例にしていますが、WebLogicやJettyやJBoss等の例も公式にはあるので実務で利用するなんて方は見てみてはいかがでしょうか。
http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file