【发布时间】:2018-04-26 01:25:34
【问题描述】:
将 Jersey 2.25 与 @NamedBinding 子资源方法一起使用不会调用过滤器。
下面getData()方法会触发AuthorizationFilter,getSubDetails()方法不会。
@NameBinding
@Retention(RUNTIME)
@Target({ TYPE, METHOD })
public @interface Secured {
Permission[] value() default {};
}
@Secured
@Provider
@Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter {
...
}
@Produces(MediaType.APPLICATION_JSON)
@Path("api/v1/jobs/{jobId}/document-sources")
@Secured(Permission.JOB_READER)
public class MyEndpoint {
@Path("/{subId}")
@GET
@Secured(Permission.READ)
public Class<?> getData(@PathParam("subId") String subId){
return "data";
}
@Path("/{subId}/details")
@Secured(Permission.READ)
public Class<?> getSubDetails(@PathParam("subId") String subId){
return SubDetails.class;
}
}
JAX-RS 文档 (https://docs.oracle.com/javaee/7/api/javax/ws/rs/container/ContainerRequestFilter.html) 似乎暗示过滤器应该在子资源上工作。
我做错了吗? NameBinding 过滤器是否不再适用于子资源方法?
【问题讨论】:
-
(关于您的第一个链接)-对我来说,测试仍然通过。出于某种原因,虽然我不能使用 1000 状态码。我冻僵了。必须在过滤器中更改为 500 状态代码。但是所有的测试仍然通过。我用的是 2.25.1。我可以看到的不同之处在于,在我的测试中,注释在子资源类上,你在定位器方法上有它。
-
感谢您指出这一点 - 单元测试的问题是响应代码为 1000。这仍然存在我需要在返回子类之前运行授权过滤器的问题(有设置在确定我返回哪个子资源所需的授权过滤器中完成的工作)。在我看来,它真的好像没有办法过滤子资源方法本身 - 只有子资源类本身......真是太糟糕了。
-
你为什么不在定位器方法中做出决定?
-
该确定需要昂贵的数据库调用。如果我们在定位器方法中做出决定,我们最终不得不在授权过滤器中重复数据库调用。当我们只使用授权过滤器时,我们可以在请求上下文中缓存该调用的结果。我们也可以在定位器方法中做到这一点,但现在我已经复制了我的授权逻辑。所以我想真正的答案是“因为它很丑”:-)
-
其实我也不知道这样行不行。我认为问题不在于名称绑定,而是在调用定位器方法之前不调用过滤器。也许是
@PreMatching过滤器?