JAX-RS/Jersey 资源路径会继承吗?
Will JAX-RS/Jersey resource paths honor inheritance?
假设我希望我的 JAX-RS/Jersey 应用公开以下 URLs:
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/*
成为 "child" 资源。以下是否会实现我正在寻找的 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
?
你要的是
@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...
}
}
Will the FizzResource
be exposed at /app/fizz
or just /fizz
?
简答
FizzResource
将在 /fizz
曝光。
长答案
引用JSR 339(第3.6节关于注释继承):
If a subclass or implementation method has any JAX-RS annotations then
all of the annotations on the superclass or interface method are
ignored.
specification 还说:
For consistency with other Java EE specifications, it is recommended to always repeat annotations instead of relying on annotation inheritance.
正在创建子资源
JAX-RS/Jersey documentation解释了如何创建子资源:
@Path
may be used on classes and such classes are referred to as root resource classes.
@Path
may also be used on methods of root resource classes. This enables common functionality for a number of resources to be grouped together and potentially reused.
The first way @Path
may be used is on resource methods and such methods are referred to as sub-resource methods.
因此,请执行以下操作来创建子资源:
@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
}
}
我认为给出的答案不是最适合原始问题陈述的答案。
他想将他的子资源放在单独的 classes 中。这是可以理解和令人钦佩的,因为不这样做将意味着将他的所有端点放在同一个 class 中,这将是巨大的。
如果此端口上的所有端点都以 /app
开头,那么我认为最好的方法是配置过滤器以将其放入 @ApplicationPath
。
如果不是所有端点都以相同的前缀开头,那么您将不得不使用这种样式的 JAX-RS 子资源,您在其中指定 @Path
而不是 HTTP 方法注释(@GET
, 等) 和 return 您要委托给的资源实例:
@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...
}
中提供了这种做资源的方法
您还可以让所有子资源将其路径声明为
@Path(BASE_URL + "/fizz")
其中 BASE_URL
是静态字符串,但我会尽量避免这种情况,因为对 @Path
使用不完全恒定的参数似乎会导致每个 JAX-RS IDE 插件我见过问题。他们无法计算出实际路径,所以他们放弃了。因此,您可能会失去 "JAX-RS View" 允许您通过路径 visualize/navigate 您的 JAX-RS 资源的能力。
假设我希望我的 JAX-RS/Jersey 应用公开以下 URLs:
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/*
成为 "child" 资源。以下是否会实现我正在寻找的 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
?
你要的是
@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...
}
}
Will the
FizzResource
be exposed at/app/fizz
or just/fizz
?
简答
FizzResource
将在 /fizz
曝光。
长答案
引用JSR 339(第3.6节关于注释继承):
If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the superclass or interface method are ignored.
specification 还说:
For consistency with other Java EE specifications, it is recommended to always repeat annotations instead of relying on annotation inheritance.
正在创建子资源
JAX-RS/Jersey documentation解释了如何创建子资源:
@Path
may be used on classes and such classes are referred to as root resource classes.
@Path
may also be used on methods of root resource classes. This enables common functionality for a number of resources to be grouped together and potentially reused.The first way
@Path
may be used is on resource methods and such methods are referred to as sub-resource methods.
因此,请执行以下操作来创建子资源:
@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
}
}
我认为给出的答案不是最适合原始问题陈述的答案。
他想将他的子资源放在单独的 classes 中。这是可以理解和令人钦佩的,因为不这样做将意味着将他的所有端点放在同一个 class 中,这将是巨大的。
如果此端口上的所有端点都以 /app
开头,那么我认为最好的方法是配置过滤器以将其放入 @ApplicationPath
。
如果不是所有端点都以相同的前缀开头,那么您将不得不使用这种样式的 JAX-RS 子资源,您在其中指定 @Path
而不是 HTTP 方法注释(@GET
, 等) 和 return 您要委托给的资源实例:
@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...
}
中提供了这种做资源的方法
您还可以让所有子资源将其路径声明为
@Path(BASE_URL + "/fizz")
其中 BASE_URL
是静态字符串,但我会尽量避免这种情况,因为对 @Path
使用不完全恒定的参数似乎会导致每个 JAX-RS IDE 插件我见过问题。他们无法计算出实际路径,所以他们放弃了。因此,您可能会失去 "JAX-RS View" 允许您通过路径 visualize/navigate 您的 JAX-RS 资源的能力。