web-dev-qa-db-ja.com

注釈のみ(web.xmlなし)を使用してJAX-RSアプリケーションを設定する方法は?

注釈のみを使用してJAX-RSアプリケーションをセットアップすることは可能ですか? (Servlet 3.0およびJAX-RS Jersey 1.1.0を使用)

試したが運がなかった。いくつかのweb.xmlを使用する必要があるようです。


構成A(機能しているが、web.xml構成があります)

web.xml

   ...
   <servlet>
      <servlet-name>org.foo.rest.MyApplication</servlet-name>
   </servlet>
   <servlet-mapping>
       <servlet-name>org.foo.rest.MyApplication</servlet-name>
       <url-pattern>/*</url-pattern>
   </servlet-mapping>
   ...

Java

@ApplicationPath("/")
public class MyApplication extends Application {
    ...
}

構成B(動作していない、例外がスローされた)

@ApplicationPath("/")
@WebServlet("/*") // <-- 
public class MyApplication extends Application {
    ...
}

後者は、アプリケーションはサーブレットのサブクラスになると主張しているようです(例外は推測を残しません)

Java.lang.ClassCastException: org.foo.rest.MyApplication cannot be cast to javax.servlet.Servlet

質問

  1. Web.xmlの定義は機能したが、アノテーションは機能しなかったのはなぜですか?違いは何ですか?

  2. それを機能させる方法はありますか? web.xmlのないJAX-RSアプリケーションがありますか?

76
Eran Medan

私がする必要があるのはこれだけだと思われます(Servlet 3.0以上)

@ApplicationPath("/*")
public class MyApplication extends Application {
    ...
}

また、明らかにweb.xml構成は必要ありませんでした(Tomcat 7で試しました)

48
Eran Medan

**​​ Tomcatを使用する場合は必ずお読みくださいOR JETTY!**

受け入れられた答えdoesは機能しますが、webappがGlassfishやWildflyなどのアプリサーバー、および場合によってはTomEEなどのEE拡張を持つサーブレットコンテナにデプロイされている場合のみです。それはしない Tomcatのような標準のサーブレットコンテナで動作します。ここでソリューションを探しているほとんどの人は使用したいと確信しています。

標準のTomcatインストール(または他のサーブレットコンテナ)を使用している場合、Tomcatには付属していないため、REST実装を含める必要があります。 Mavenを使用している場合、これをdependenciesセクションに追加します。

<dependencies>
  <dependency>
    <groupId>org.glassfish.jersey.bundles</groupId>
    <artifactId>jaxrs-ri</artifactId>
    <version>2.13</version>
  </dependency>
  ...
</dependencies>

次に、アプリケーション構成クラスをプロジェクトに追加します。残りのサービスのコンテキストパスの設定以外に特別な構成が必要ない場合は、クラスを空にすることができます。このクラスが追加されたら、web.xmlで何も設定する必要はありません(またはまったく設定する必要はありません):

package com.domain.mypackage;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("rest") // set the path to REST web services
public class ApplicationConfig extends Application {}

この後、Javaクラスで標準のJAX-RSアノテーションを使用して、Webサービスを宣言するのは簡単です。

package com.domain.mypackage;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;

// It's good practice to include a version number in the path so you can have
// multiple versions deployed at once. That way consumers don't need to upgrade
// right away if things are working for them.
@Path("calc/1.0")
public class CalculatorV1_0 {
  @GET
  @Consumes("text/plain")
  @Produces("text/plain")
  @Path("addTwoNumbers")
  public String add(@MatrixParam("firstNumber") int n1, @MatrixParam("secondNumber") int n2) {
    return String.valueOf(n1 + n2);
  }
}

必要なのはこれだけです。 Tomcatインストールがポート8080でローカルに実行されており、WARファイルをコンテキストmyContextにデプロイしている場合、...

http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3

...期待される結果が得られるはずです(5)。

158
Alvin Thompson

JAX-RS:RESTful Webサービス用Java™API 仕様の第2章では、サーブレット環境でのJAX-RSアプリケーションの公開プロセスについて説明しています(セクション2.3.2仕様のサーブレット)。

サーブレット3環境のみが推奨されることに注意してください(6ページのセクション2.3.2サーブレット)。

実装は、サーブレット3フレームワークのプラガビリティメカニズムをサポートして、コンテナ間の移植性を可能にし、コンテナが提供するクラススキャン機能を利用することをお勧めします。

つまり、no-web.xmlアプローチを使用したい場合は、 javax.ws.rs.core.Application のカスタム実装を使用して、RESTfulサービスリソースを javax.ws.rs.ApplicationPath アノテーション。

@ApplicationPath("/rest")

ジャージーについて具体的に尋ねましたが、記事 JAX-RSおよびWebSphere 8.5 Liberty Profileを使用したRESTfulサービスの実装 で、no-web.xmlの公開プロセスについて説明しました WebSphere Liberty Profile (JAX-RSの実装としてApache Winkを使用)。

14
Jacek Laskowski

Pom.xmlで適切な依存関係を設定する必要があります

<dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
    </dependency>

詳細はこちら: jax-rsのスターター例

6
ACV

前述の依存関係は機能しませんでした。 Jerseyユーザーガイドから:

Jerseyは2つのサーブレットモジュールを提供します。最初のモジュールは、コアサーブレット統合サポートを提供するジャージーコアサーブレットモジュールで、サーブレット2.5以降のコンテナで必要です。

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

追加のServlet 3.xデプロイメントモードと非同期JAX-RSリソースプログラミングモデルをサポートするには、追加のJerseyモジュールが必要です。

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

Jersey-container-servletモジュールはjersey-container-servlet-coreモジュールに依存するため、使用する場合、jersey-container-servlet-core依存関係を明示的に宣言する必要はありません。

https://jersey.github.io/documentation/latest/deployment.html#deployment.servlet.

0
bzak

@ Eran-Medanが指摘したように、JBoss EAP 7.1(Webアプリケーションがないのでサーブレットがないので、EJB 3.2プロジェクトでそれを行っていました)値属性が必要でした。

これは私のために働いた

    @ApplicationPath(value="/*")
        public class MyApplication extends Application {

            private Set singletons = new HashSet();

            public MyApplication() {
                singletons.add(new MyService());
            }

            ...
    }

スタックトレース

    Caused by: Java.lang.annotation.IncompleteAnnotationException: javax.ws.rs.ApplicationPath missing element value
        at Sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.Java:80)
        at com.Sun.proxy.$Proxy141.value(Unknown Source)
        ... 21 more
0
JGlass