Jersey/REST: 将请求委托给不同的子资源而不重复代码?
Jersey/REST: delegating requests to different sub resources without code duplication?
我们创建了一个资源,例如:
@Path("whatever")
public class WhateverResource {
@POST
public Response createWhatever(CreateBean bean) { ...
@DELETE
@Path("/{uuid}")
public void deleteWhatever(@PathParam("uuid") UUID uuid) { ...
GET、PUT、HEAD 依此类推。
现在我们认为我们认为我们需要检查底层功能是否实际启用。一次检查,当它失败时,所有操作都应该简单地导致 501。
我的第一个想法是复制现有资源,例如:
@Path("whatever")
public class WhateverResourceIsntAvailable {
@POST
public Response createWhatever(CreateBean bean) {
throw 501
@DELETE
@Path("/{uuid}")
public void deleteWhatever(@PathParam("uuid") UUID uuid) {
throw 501
因此,两个资源都指定了完全相同的操作。导致我们无法(轻松地)在需要注册资源的时间点调用该检查的问题。
除此之外,这个复制看起来不太优雅,我想知道是否有解决这个问题的"more canonical"方法?
编辑:另一种选择是将检查添加到现有资源中,添加到每个资源中,但这意味着:对每个操作进行检查。添加新操作时很容易忘记。
我设想的是:
- a "base resource",已注册
- 当对该资源调用 任何 操作时,请求应该是 "delegated",具体取决于底层功能
- 或者总是给 501 的资源
- 或执行实际工作的"real"资源
理想情况下,无需复制检查代码或复制操作端点规范。
根据用户 Samsotha 的建议,我实现了一个简单的 filter, which is then "connected" via name binding,例如:
@Path("whatever")
@MyNewFilter
public class WhateverResource {
...
并且:
@MyNewFilter
public class MyNewFilterImpl implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext context) {
if (... feature is enabled )) {
... nothing to do
} else {
context.abortWith(
Response.status(Response.Status.NOT_IMPLEMENTED).entity("not implemented").build());
}
}
这种方法的主要优点是可以注释单个操作,也可以注释整个资源,例如我的 WhateverResource
。后者将确保该资源中的 any 操作正在通过过滤器!
(可以在任何像样的 Jersey 教程中找到更多详细信息,例如 baeldung 中的教程)
我们创建了一个资源,例如:
@Path("whatever")
public class WhateverResource {
@POST
public Response createWhatever(CreateBean bean) { ...
@DELETE
@Path("/{uuid}")
public void deleteWhatever(@PathParam("uuid") UUID uuid) { ...
GET、PUT、HEAD 依此类推。
现在我们认为我们认为我们需要检查底层功能是否实际启用。一次检查,当它失败时,所有操作都应该简单地导致 501。
我的第一个想法是复制现有资源,例如:
@Path("whatever")
public class WhateverResourceIsntAvailable {
@POST
public Response createWhatever(CreateBean bean) {
throw 501
@DELETE
@Path("/{uuid}")
public void deleteWhatever(@PathParam("uuid") UUID uuid) {
throw 501
因此,两个资源都指定了完全相同的操作。导致我们无法(轻松地)在需要注册资源的时间点调用该检查的问题。
除此之外,这个复制看起来不太优雅,我想知道是否有解决这个问题的"more canonical"方法?
编辑:另一种选择是将检查添加到现有资源中,添加到每个资源中,但这意味着:对每个操作进行检查。添加新操作时很容易忘记。
我设想的是:
- a "base resource",已注册
- 当对该资源调用 任何 操作时,请求应该是 "delegated",具体取决于底层功能
- 或者总是给 501 的资源
- 或执行实际工作的"real"资源
理想情况下,无需复制检查代码或复制操作端点规范。
根据用户 Samsotha 的建议,我实现了一个简单的 filter, which is then "connected" via name binding,例如:
@Path("whatever")
@MyNewFilter
public class WhateverResource {
...
并且:
@MyNewFilter
public class MyNewFilterImpl implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext context) {
if (... feature is enabled )) {
... nothing to do
} else {
context.abortWith(
Response.status(Response.Status.NOT_IMPLEMENTED).entity("not implemented").build());
}
}
这种方法的主要优点是可以注释单个操作,也可以注释整个资源,例如我的 WhateverResource
。后者将确保该资源中的 any 操作正在通过过滤器!
(可以在任何像样的 Jersey 教程中找到更多详细信息,例如 baeldung 中的教程)