假设我希望我的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...
}
}