2

我最近遇到了一种情况,我想在一个 Spring MVC Web 应用程序中使用两个独立的 Jersey 应用程序。我创建了两个映射到不同 URI 的独立 servlet,以及两个具有相同路径的独立根资源类。

应用程序 1 Servlet:

<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
}

应用程序初始化期间抛出的 Jersey 异常:

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(/.*)?

由于这些是两个独立的应用程序和两个独立的 servlet,我期待它能够工作。这在泽西岛是不可能的还是有不同的方法?

4

1 回答 1

0

我看到多个问题:

  1. 不要对应用程序和资源使用相同的类。资源是按请求实例化的。这意味着构造函数应该是轻量级的。您不想为收到的每个请求实例化 PackagesResourceConfig。即对应用程序使用单独的类,对资源使用单独的类。
  2. 您的所有代码都位于一个包中,并且您正在使用包扫描。这意味着,当 App1Root 被 servlet 实例化时,它会扫描 private.api.rest 包(以及所有子包)的包(因为您继承自 PackagesResourceConfig),发现 App1Root 和 App2Root 都使用相同的 @Path 注释并失败。

您可以通过拆分资源和应用程序并将 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 回答