1. 序章

JAX-RS (RESTfulWebサービス用のJavaAPI)は、 RESTAPIの作成をサポートするJavaAPIのセットです。 また、フレームワークはアノテーションをうまく利用して、これらのAPIの開発とデプロイを簡素化します。

このチュートリアルでは、単純なRESTful Webサービスを作成するために、JBossが提供するJAX-RS仕様のポータブル実装であるRESTEasyを使用します。

2. プロジェクトの設定

2つの可能なシナリオを検討します。

  • スタンドアロンセットアップ–すべてのアプリケーションサーバーでの作業を目的としています
  • JBoss ASセットアップ–JBossASでのデプロイメントのみを検討します

2.1. スタンドアロンセットアップ

スタンドアロンセットアップでJBossWildFly10を使用することから始めましょう。

JBoss WildFly 10にはRESTEasyバージョン3.0.11が付属していますが、ご覧のとおり、pom.xmlを新しい3.0.14バージョンで設定します。

また、 resteasy-servlet-initializer のおかげで、RESTEasyは、ServletContainerInitializer統合インターフェースを介してスタンドアロンのサーブレット3.0コンテナーとの統合を提供します。

pom.xml を見てみましょう

<properties>
    <resteasy.version>3.0.14.Final</resteasy.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-servlet-initializer</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
</dependencies>

jboss-deployment-structure.xml

JBoss内では、WAR、JAR、またはEARとしてデプロイされるすべてがモジュールです。 これらのモジュールは、動的モジュールと呼ばれます。

これらのほかに、 $ JBOSS_HOME /modulesにいくつかのstaticモジュールもあります。 JBossにはRESTEasy静的モジュールがあるため、スタンドアロンデプロイメントの場合、それらの一部を除外するにはjboss-deployment-structure.xmlが必須です。

このようにして、WARに含まれるすべてのクラスとJARファイルがロードされます。

<jboss-deployment-structure>
    <deployment>
        <exclude-subsystems>
            <subsystem name="resteasy" />
        </exclude-subsystems>
        <exclusions>
            <module name="javaee.api" />
            <module name="javax.ws.rs.api"/>
            <module name="org.jboss.resteasy.resteasy-jaxrs" />
        </exclusions>
        <local-last value="true" />
    </deployment>
</jboss-deployment-structure>

2.2. セットアップとしてのJBoss

JBossバージョン6以降でRESTEasyを実行する場合は、アプリケーションサーバーにすでにバンドルされているライブラリを採用することを選択できるため、pomが単純化されます。

<dependencies>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxrs</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
<dependencies>

jboss-deployment-structure.xmlは不要になっていることに注意してください。

3. サーバーサイドコード

3.1. サーブレットバージョン3 web.xml

ここで、単純なプロジェクトのweb.xmlを簡単に見てみましょう。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

   <display-name>RestEasy Example</display-name>

   <context-param>
      <param-name>resteasy.servlet.mapping.prefix</param-name>
      <param-value>/rest</param-value>
   </context-param>

</web-app>

resteasy.servlet.mapping.prefix は、APIアプリケーションへの相対パスを付加する場合にのみ必要です。

この時点で、 resteasy servlet-initializer のため、web.xmlサーブレットを宣言していないことに注意することが非常に重要です。 ]がpom.xmlに依存関係として追加されました。 その理由は–RESTEasyはjavax.server.ServletContainerInitializerを実装するorg.jboss.resteasy.plugins.servlet.ResteasyServletInitializerクラスを提供します。

ServletContainerInitializer は初期化子であり、サーブレットコンテキストの準備が整う前に実行されます。この初期化子を使用して、アプリのサーブレット、フィルター、またはリスナーを定義できます。

3.2. アプリケーションクラス

javax.ws.rs.core.Application クラスは、デプロイメントに関する情報を提供するために実装できる標準のJAX-RSクラスです。

@ApplicationPath("/rest")
public class RestEasyServices extends Application {

    private Set<Object> singletons = new HashSet<Object>();

    public RestEasyServices() {
        singletons.add(new MovieCrudService());
    }

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}

ご覧のとおり、これはすべてのJAX-RSルートリソースとプロバイダーを一覧表示する単なるクラスであり、@ApplicationPathアノテーションが付けられています。

クラスおよびシングルトンによって空のセットを返す場合、WARはJAX-RSアノテーションリソースおよびプロバイダークラスについてスキャンされます。

3.3. サービス実装クラス

最後に、ここで実際のAPI定義を見てみましょう。

@Path("/movies")
public class MovieCrudService {

    private Map<String, Movie> inventory = new HashMap<String, Movie>();

    @GET
    @Path("/getinfo")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public Movie movieByImdbId(@QueryParam("imdbId") String imdbId) {
        if (inventory.containsKey(imdbId)) {
            return inventory.get(imdbId);
        } else {
            return null;
        }
    }

    @POST
    @Path("/addmovie")
    @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public Response addMovie(Movie movie) {
        if (null != inventory.get(movie.getImdbId())) {
            return Response
              .status(Response.Status.NOT_MODIFIED)
              .entity("Movie is Already in the database.").build();
        }

        inventory.put(movie.getImdbId(), movie);
        return Response.status(Response.Status.CREATED).build();
    }
}

4. 結論

このクイックチュートリアルでは、RESTEasyを紹介し、それを使用して非常にシンプルなAPIを構築しました。

この記事で使用されている例は、GitHubサンプルプロジェクトとして利用できます。