Java 未对子资源方法调用Jersey NameBinding筛选器

Java 未对子资源方法调用Jersey NameBinding筛选器,java,jersey,Java,Jersey,将Jersey 2.25与@NamedBinding子资源方法一起使用不会调用筛选器 在下面的示例中,getData()方法触发AuthorizationFilter,但getSubDetails()方法不触发 @NameBinding @Retention(RUNTIME) @Target({ TYPE, METHOD }) public @interface Secured { Permission[] value() default {}; } @Secured @Provid

将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;
    }
}
@NameBinding
@保留(运行时)
@目标({TYPE,METHOD})
公共@接口安全{
权限[]值()默认值{};
}
@安全的
@提供者
@优先级(优先级.授权)
公共类AuthorizationFilter实现ContainerRequestFilter{
...
}
@产生(MediaType.APPLICATION_JSON)
@路径(“api/v1/jobs/{jobId}/documentsources”)
@安全(权限.作业\u读取器)
公共类MyEndpoint{
@路径(“/{subId}”)
@得到
@安全(权限。读取)
公共类getData(@PathParam(“subId”)字符串subId){
返回“数据”;
}
@路径(“/{subId}/details”)
@安全(权限。读取)
公共类getSubDetails(@PathParam(“subId”)字符串subId){
返回SubDetails.class;
}
}
JAX-RS文档()似乎暗示过滤器应该在子资源上工作


我做错什么了吗?名称绑定筛选器不再应用于子资源方法吗?

对于遇到此问题的任何其他人:

子资源定位器方法没有针对它们运行NameBinding筛选器(至少在Jersey中是这样)。我找不到任何说明这是否正确的文档

在我们的例子中,过滤器很重要,因为它将对象添加到请求上下文中,定位器方法使用这些对象来确定返回哪个子资源。这些对象的创建有点昂贵(涉及数据库调用),所以我们不想只在子资源定位器方法中复制对象创建代码(加上这会违反DRY)


我最后使用的解决方案是将对象创建逻辑移动到工厂中,并让工厂使用请求上下文缓存,以确保它只执行一次对象初始化。然后在过滤器(用于授权)和子资源方法(用于确定要发送的子资源)中使用工厂。然后每个子资源都必须有授权过滤器注释。

(关于您的第一个链接)-对我来说,测试仍然通过。由于某种原因,我不能使用1000状态码。我觉得冷极了。必须将过滤器中的状态代码更改为500。但是所有的测试都通过了。我用了2.25.1。我可以看到的区别是,在我的测试中,注释在子资源类上,而在locator方法上有注释。感谢您指出——单元测试的问题是响应代码是1000。这仍然存在一个问题,即我需要在返回子类之前运行授权筛选器(授权筛选器中完成了确定我返回的子资源所需的设置工作)。在我看来,似乎没有办法对子资源方法本身进行过滤——只有子资源类本身。。。这太糟糕了。为什么不使用locator方法进行确定?确定需要昂贵的数据库调用。如果我们在locator方法中进行确定,那么我们必须在授权过滤器中重复数据库调用。当我们只使用授权过滤器时,我们可以在请求上下文中缓存该调用的结果。我们也可以在locator方法中这样做,但是现在我已经复制了我的授权逻辑。所以我想真正的答案是“因为它很丑”:-)事实上,我也不知道这是否有效。我认为问题不在于名称绑定,而是在调用定位器方法之前不调用过滤器。可能是一个
@预匹配的
过滤器?