多个Jersey应用程序具有相同的根资源路径

时间:2012-04-19 15:48:37

标签: spring jersey jax-rs

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

应用程序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>
    <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,我希望这可以工作。这在泽西岛是不可能的,还是有不同的方法?

1 个答案:

答案 0 :(得分:0)

我看到了多个问题:

  1. 不要将相同的类用于应用程序和资源。资源按请求实例化。这意味着构造函数应该是轻量级的。您不希望为每个请求实例化PackagesResourceConfig。即为应用程序使用单独的类,为资源使用单独的类。
  2. 您的所有代码都位于一个程序包中,并且您正在使用程序包扫描。这意味着,当App1Root由servlet实例化时,它执行private.api.rest包(以及所有子包)的包扫描(因为你继承了PackagesResourceConfig),发现App1Root和App2Root都使用相同的@Path进行注释并失败。
  3. 您可以通过拆分资源和应用并将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
    }