2

私は最近、1 つの Spring MVC Web アプリに 2 つの個別の Jersey アプリケーションが必要な状況に遭遇しました。異なる URI にマップする 2 つの別個のサーブレットと、同じパスを持つ 2 つの別個のルート リソース クラスを作成しました。

アプリケーション 1 サーブレット:

<servlet>
    <servlet-name>JerseyServlet1</servlet-name>
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>

    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>public.api.rest.Application1</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>JerseyServlet1</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

アプリケーション 2 サーブレット:

<servlet>
    <servlet-name>JerseyServlet2</servlet-name>
    <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>

    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>private.api.rest.Application2</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>JerseyServlet2</servlet-name>
    <url-pattern>/internal/*</url-pattern>
</servlet-mapping>

アプリケーション 1:

package public.api.rest;

public class Application1 extends PackagesResourceConfig {
    public Application1(){
        super(Application1.class.getPackage().getName());
    }
}

アプリケーション 2:

package private.api.rest;

public class Application2 extends PackagesResourceConfig {
    public Application2(){
        super(Application2.class.getPackage().getName());
    }
}

アプリケーション 1 ルート リソース:

package public.api.rest;

@Path("release-1")
@Component
@Scope("request")
public class App1Root{
    //resource methods
}

アプリケーション 2 ルート リソース:

package private.api.rest;

@Path("release-1")
@Component
@Scope("request")
public class App2Root{
    //resource methods
}

アプリケーションの初期化中にジャージー例外がスローされました:

SEVERE: The following errors and warnings have been detected with resource and/or provider classes:
  SEVERE: Conflicting URI templates. The URI template /release-1 for root resource class private.api.rest.App2Root and the URI template /release-1 transform to the same regular expression /release-1(/.*)?

これらは 2 つの別個のアプリケーションと 2 つの別個のサーブレットであるため、これが機能することを期待していました。これはジャージーでは不可能ですか、それとも別のアプローチがありますか?

4

1 に答える 1

0

複数の問題があります。

  1. アプリケーションとリソースに同じクラスを使用しないでください。リソースはリクエストごとにインスタンス化されます。つまり、コンストラクターは軽量である必要があります。来るすべてのリクエストに対してPackagesResourceConfigをインスタンス化する必要はありません。つまり、アプリケーション用に別のクラスを使用し、リソース用に別のクラスを使用します。
  2. すべてのコードが1つのパッケージに含まれており、パッケージスキャンを使用しています。つまり、App1Rootがサーブレットによってインスタンス化されると、private.api.restパッケージ(およびすべてのサブパッケージ)のパッケージスキャン(PackagesResourceConfigから継承するため)が実行され、同じ@Pathで注釈が付けられたApp1RootとApp2Rootの両方が検出されます。そして失敗します。

これを修正するには、リソースとアプリを分割し、app1のリソースをapp2とは異なるパッケージに配置します。たとえば、次のように機能するはずです。

アプリケーション1:

package private.api.rest;

public class App1Root  extends PackagesResourceConfig {
    public App1Root(){
        super("private.api.rest.app1");
    }
}

アプリケーション2:

package private.api.rest;

public class App2Root  extends PackagesResourceConfig {
    public App2Root(){
        super("private.api.rest.app2");
    }
}

リソースクラス1:

package public.api.rest.app1;

@Path("release-1")
@Component
@Scope("request")
public class App1Root {
    // resource methods here
}

リソースクラス2:

package public.api.rest.app2;

@Path("release-1")
@Component
@Scope("request")
public class App1Root {
    // resource methods here
}
于 2012-04-27T07:46:47.220 に答える