Maven2使い方メモ２（Tomcat で JAX-RS）

Maven で Tomcat で動作する Web アプリの作り方をメモ。
単純な Servlet だけのやつと、 JAX-RS(Jersey) を使ったやつの２つを作成する。


#環境
##OS
Windows7 64bit

##Java
1.7.0_25

##Tomcat
7.0.42

##Jersey
2.2

#単純な Servlet だけの Web アプリ
##プロジェクトのひな形を作成する
コマンドプロンプトから任意のフォルダで以下のコマンドを実行する。

```batch:ひな形の作成
>mvn archetype:create -DgroupId=com.example.servlet -DartifactId=servlet-sample -DarchetypeArtifactId=maven-archetype-webapp
```

以下のようなひな形が出力される。

```text:作成されたひな形の構成
servlet-sample>tree /f
│  pom.xml
│
└─src
    └─main
        ├─resources
        └─webapp
            │  index.jsp
            │
            └─WEB-INF
                    web.xml
```

##Servlet を実装する
`src/main/java/com/example/servlet` フォルダを作成して、 `SampleServlet.java` を作成する。

```java:SampleServlet.java
package com.example.servlet;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;

import java.io.IOException;

@WebServlet("/sample")
public class SampleServlet extends HttpServlet {
    
    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
        ServletOutputStream os = res.getOutputStream();
        os.println("Sample Page");
    }
}
```

###web.xml を削除する
サーブレットのマッピングは `@WebServlet` アノテーションで指定しているので、 `sample-servlet/src/main/webapp/WEB-INF/web.xml` を削除する。

##pom.xml を編集する
`pom.xml` を以下の内容に編集する。

```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.servlet</groupId>
  <artifactId>sample-servlet</artifactId>
  <packaging>war</packaging>
  <version>1.0</version>
  
  <name>Sample Maven Webapp</name>
  
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  
  <build>
    <finalName>sample-servlet</finalName>
    
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
      
      <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-war-plugin</artifactId>
          <version>2.3</version>
          <configuration>
              <failOnMissingWebXml>false</failOnMissingWebXml>
          </configuration>
      </plugin>
    </plugins>
  </build>
</project>
```

###failOnMissingWebXml について
この設定をしないと、 `war` を作るときに `web.xml` が無くてエラーになる。
`web.xml` は削除しているので、 `failOnMissingWebXml` に `false` を指定している。

##war を作成する
以下のコマンドを実行する。

```batch:warの作成
sample-servlet>mvn package
```

`target` フォルダの下に `sample-servlet.war` という `war` ファイルが出力される。

##動作確認
`sample-servlet.war` を Tomcat に配備して、 Tomcat を起動。
`http://localhost:8080/sample-servlet/sample` にブラウザからアクセスする（ポート番号は適宜読み替え）。

![実行画面](https://qiita-image-store.s3.amazonaws.com/0/28302/b4151918-4473-7f33-5db6-20590ae2f8eb.jpeg)


#JAX-RS を使用した Web アプリ
##ひな形の作成
コマンドプロンプトから任意のフォルダで以下のコマンドを実行する。

```batch:ひな形の作成
>mvn archetype:create -DgroupId=com.example.jaxrs -DartifactId=jaxrs-sample -DarchetypeArtifactId=maven-archetype-webapp
```

##JAX-RS のサービスクラスを作成する
`src/main/java/com/example/jaxrs` フォルダを作成して、 `SampleResource.java` を作成する。

```java:SampleResource.java
package com.example.jaxrs;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("sample")
public class SampleResource {
    
    @GET
    public String sample() {
        return "Sample Resource";
    }
}
```

##web.xml に Jersey のサーブレットを登録する
```xml:web.xml
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>JAX-RS Sample Application</display-name>
  
  <servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.example.jaxrs</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
  
</web-app>
```

###説明
`init-param` で指定している `jersey.config.server.provider.packages` には、 JAX-RS のサービスクラスを検索するパッケージを指定する。
サービスクラスの検索はサブパッケージも再帰的に実行される。

```xml:検索パッケージの指定
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.example.jaxrs</param-value>
    </init-param>
```

複数のパッケージを指定したい場合は、セミコロン（`;`）区切りで列挙できる。

```xml:検索パッケージを複数記述
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.hoge.jaxrs;com.fuga.jaxrs</param-value>
    </init-param>
```

##pom.xml の編集
`pom.xml` を以下のように編集する。

```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.jaxrs</groupId>
  <artifactId>jaxrs-sample</artifactId>
  <packaging>war</packaging>
  <version>1.0</version>
  
  <name>JAX-RS Maven Webapp</name>
  
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <!-- Servlet コンテナのバージョンが 3.0 より古い場合は "jersey-container-servlet-core" を指定する -->
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.2</version>
    </dependency>
  </dependencies>
  
  <build>
    <finalName>jaxrs-sample</finalName>
    
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
    
  </build>
</project>
```

##war の作成
以下のコマンドを実行する。

```batch:warの作成
jaxrs-servlet>mvn package
```

`target` フォルダの下に `jaxrs-servlet.war` という `war` ファイルが出力される。

##動作確認
`jaxrs-servlet.war` を Tomcat に配備して、 Tomcat を起動。
`http://localhost:8080/jaxrs-servlet/rest/sample` にブラウザからアクセスする（ポート番号は適宜読み替え）。

![無題.jpg](https://qiita-image-store.s3.amazonaws.com/0/28302/8c0fd9b3-2f47-91e3-3142-71641d594685.jpeg)

#参考
+ [5. Maven による実アプリケーション開発 | TECHSCORE(テックスコア)](http://www.techscore.com/tech/Java/ApacheJakarta/Maven/5/)
+ [Chapter 2. Modules and dependencies](https://jersey.java.net/documentation/latest/modules-and-dependencies.html)
+ [Chapter 4. Deploying a RESTful Web Service](https://jersey.java.net/documentation/latest/deployment.html)
+ [Jersey + Tomcat で REST サービス at technote](http://blog.withsin.net/2012/04/04/jersey-tomcat-rest/)