Jerseyの設定2(web.xmlとかApplicationクラスとか)

前回の続きでServlet3.xで動かす場合の設定。
Chapter 4. Application Deployment and Runtime Environments

Servlert3.x

pom.xml

前回にも書いたが、Servlet2.xと3.xでは使用するモジュールが異なる。

    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
        </dependency>
    </dependencies>

2.xではjersey-container-servlet-coreを使用するが、3.xではjersey-container-servlet

Applicationとweb.xmlの関係

公式ドキュメントにはApplication(のサブクラス)とweb.xmlの関係が表になっている。

条件(Application) Jerseyの動き servlet-name web.xml
(1) サブクラス無し Servlet追加 javax.ws.rs.core.Application servlet-mapping必要
(2) サブクラスがServletでハンドリング 何もしない 定義済み 不要
(3) サブクラスがハンドリングされていない Servlet追加 サブクラス完全名 @ApplicationPathが指定されていなければservlet-mapping必要

(1)パターン

Applicationサブクラスを作らない場合、web.xml必須。

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <servlet>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
  </servlet>
  <servlet-mapping>
    <servlet-name>javax.ws.rs.core.Application</servlet-name>
    <url-pattern>/webapi/*</url-pattern>
  </servlet-mapping>
</web-app>

servlet > servlet-nameにjavax.ws.rs.core.Applicationを指定する。
servlet-mappingを指定して、servlet-nameとurl-patternを指定する。
この場合、@Pathや@Providerが付いたクラスを自動でJAX-RSアプリケーションとして読み込んでくれる。便利。
(xmlだけで言えば)Jersey依存していないので、Jersey独自機能とか使わなければこれで問題なし。

余談:前回の自動生成されたweb.xmlをそのまま使うとschemaLocationでxmlがチェックされてxmlがエラーになるので注意。
web-appタグを公式ドキュメントと同じにするか、「2.5」「2_5」となっている箇所を「3.0」「3_0」に書き換える。

(2)パターン

Application(or ResourceConfig)のサブクラスを作って@ApplicationPathを指定すれば、web.xml不要。

@ApplicationPath("webapi")
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        packages("mypackage.test.resources");
    }
}

@ApplicationPathは、web.xmlで指定していたurl-patternと同様。
Applicationのサブクラス with @ApplicationPathを作れば、web.xmlは空でいい。

<web-app>
</web-app>

更にmavenプラグインを使えば、web.xmlのファイルが無くてもOKになる。
(war作成時にエラーにならない)

<plugins>
    ...
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.3</version>
        <configuration>
            <failOnMissingWebXml>false</failOnMissingWebXml>
        </configuration>
    </plugin>
    ...
</plugins>

failOnMissingWebXmlをfalseにする。

(3)パターン

Applicationのサブクラスがハンドリングされない場合、というのが具体的にどんな時なのかが分からない。
web.xmlServlet定義されている場合(If the web.xml contains a Servlet definition)、でいいのかな?
とりあえずハンドリングされない場合は(3)パターンを使う。

public class MyApplication extends ResourceConfig {
    public MyApplication() {
        packages("mypackage.test.resources");
    }
}
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <servlet>
    <servlet-name>mypackage.test.MyApplication</servlet-name>
  </servlet>
  <servlet-mapping>
    <servlet-name>mypackage.test.MyApplication</servlet-name>
    <url-pattern>/webapi/*</url-pattern>
  </servlet-mapping>
</web-app>

servlet-nameにApplicationサブクラスの完全修飾名を指定する。
@ApplicationPathを指定していればservlet-mappingは不要。
@ApplicationPath未指定であればservlet-mapping必要。