JAX-RS/Jersey资源路径是否尊重继承



假设我希望我的JAX-RS/Jerssey应用程序公开以下URL:

http://myapp.example.com/app/fizz
http://myapp.example.com/app/buzz
http://myapp.example.com/app/foo
http://myapp.example.com/app/bar

假设我希望/app是父基础资源,/app/*是"子"资源。以下会实现我正在寻找的URL策略吗(?):

@Path('/app')
@Produces(MediaType.APPLICATION_JSON)
public abstract class AppResource {
    // Whatever...
}
@Path('/fizz') // <--- right here, will FizzResource live at /app/fizz?
@Produces(MediaType.APPLICATION_JSON)
public class FizzResource extends AppResource {
    // Whatever...
}

FizzResource是在/app/fizz还是仅在/fizz暴露

FizzResource是在/app/fizz暴露还是仅在/fizz暴露?

简短回答

CCD_ 9将在CCD_。

答案很长

引用JSR339(关于注释继承3.6部分):

如果子类或实现方法具有任何JAX-RS注释,则超类或接口方法上的所有注释都是已忽略。

规范还说:

为了与其他Java EE规范保持一致,建议始终重复注释,而不是依赖注释继承

创建子资源

JAX-RS/Jersey文档解释了如何创建子资源:

CCD_ 11可以用于类,并且这样的类被称为根资源类。

CCD_ 12也可以用于根资源类的方法。这使得许多资源的通用功能能够分组在一起并可能被重用。

可以使用@Path的第一种方式是资源方法,并且这种方法被称为子资源方法

因此,请执行以下操作来创建子资源:

@Path("/app")
public class YourHandler {
    @Produces(MediaType.APPLICATION_JSON)
    public String yourHandlerForApp() {
        // This method is be exposed at /app
    }
    @Path("/fizz") 
    @Produces(MediaType.APPLICATION_JSON)
    public String yourHandlerForAppSlashFizz() {
        // This method is be exposed at /app/fizz
    }
}

我不认为给出的答案对最初的问题陈述是最好的。

他想把他的子资源放在不同的类中。这是可以理解的,也是令人钦佩的,因为不这样做意味着把他的所有端点都放在同一个类中,这将是巨大的。

如果这个端口上的所有端点都以/app开头,那么我认为最好的方法是将过滤器配置为将其放入@ApplicationPath中。

如果不是所有端点都以相同的前缀开头,那么您将不得不使用这种风格的JAX-RS子资源,在其中指定@Path而不是HTTP方法注释(@GET等),并返回要委托给的资源的实例:

@Path("/app")
public class AppResource {
    @Context UriInfo uriInfo;
    @Path("fizz")
    public FizzResource getItemContentResource() {
        return new FizzResource ();
    }
}
@Produces(MediaType.APPLICATION_JSON)
public class FizzResource extends AppResource {
    // Whatever...
}

JAX-RS文档中提供了这种获取资源的方法。

您还可以让所有子资源将其路径声明为

    @Path(BASE_URL + "/fizz")

其中BASE_URL是一个静态字符串,但我会尽量避免这种情况,因为对@Path使用一个不完全恒定的参数似乎会导致我看到的每个JAX-RSIDE插件都出现问题。他们无法计算出实际的路径,所以他们放弃了。因此,您可能会失去拥有"JAX-RS视图"的能力,该视图允许您通过路径可视化/导航JAX-RS资源。

您想要的是

@Path("/app")
public class YourHandler {
   @Path('/')
   @Produces(MediaType.APPLICATION_JSON)
   public String yourHandlerForApp() {
      // Whatever...
   }
   @Path('/fizz') // <--- right here, will FizzResource live at /app/fizz?
   @Produces(MediaType.APPLICATION_JSON)
   public String yourHandlerForAppSlashFizz() {
       // Whatever...
   }
}

最新更新