将 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 过滤器是否不再适用于子资源方法?
最佳答案
对于遇到此问题的其他人:
子资源定位器方法没有针对它们运行的 NameBinding 过滤器(至少在 Jersey )。我找不到任何说明这是否正确的文档。
在我们的例子中,过滤器很重要,因为它将对象添加到请求上下文中,定位器方法使用这些对象来确定要返回哪个子资源。这些对象的创建有些昂贵(涉及数据库调用),因此我们不想只在子资源定位器方法中复制对象创建代码(而且这会违反 DRY)。
我最终采用的解决方案是将对象创建逻辑移动到工厂中,并让工厂使用请求上下文缓存来确保它只进行一次对象初始化。然后在过滤器(用于授权)和子资源方法(用于确定要发送的子资源)中使用工厂。然后每个子资源都必须有授权过滤器注释。
关于java - 未在子资源方法上调用 Jersey NameBinding 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50033492/