Spring 如何在CXF中的ContainerRequestFilter中注入ResourceInfo

Spring 如何在CXF中的ContainerRequestFilter中注入ResourceInfo,spring,rest,jax-rs,cxf,ws-security,Spring,Rest,Jax Rs,Cxf,Ws Security,我正在尝试使用ApacheCXF和Spring构建一个基于令牌的身份验证和授权系统。我完全赞同这样做。 但我在一开始就遇到了授权过滤器的问题。我看过很多帖子,ApacheJira,github对它的评论,但是还没有找到解决这个看似CXF问题的方法 @PreMatching @Priority(Priorities.AUTHORIZATION) public class AuthorizationFilter implements ContainerRequestFilter { private

我正在尝试使用ApacheCXF和Spring构建一个基于令牌的身份验证和授权系统。我完全赞同这样做。 但我在一开始就遇到了授权过滤器的问题。我看过很多帖子,ApacheJira,github对它的评论,但是还没有找到解决这个看似CXF问题的方法

@PreMatching
@Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter {
private ResourceInfo resourceInfo;

@Context
public void setResourceInfo(ResourceInfo resourceInfo) {
    this.resourceInfo = resourceInfo;
}

@Override
public void filter(final ContainerRequestContext requestContext) throws IOException {

    Method method = resourceInfo.getResourceMethod();
在上面的代码中,注入的resourceInfo是一个代理对象,并且它没有任何相关属性。因此,来自
resourceInfo
对象的任何内容都返回
null
,更具体地说,
resourceInfo.getResourceMethod()
null
,导致NPE。 这是一篇关于这个问题的帖子,上面说:

在某些情况下(例如使用@ApplicationScoped注释),CDI运行时将为特定bean创建代理类。因此,CXF端将把特定的提供者元数据绑定到此代理实例。它看起来逻辑清晰

然而,当CXF尝试将上下文代理(@Context annotations)注入到提供者实例时,有趣的事情正在发生。注入是成功的,但它们的目标对象将是代理实例(而不是其背后的真实实例)。因此,在运行时,当代理将调用委托给支持实例时,其中的所有上下文代理都为null(简单地说,不是设置)

参考最近与Sergey Beryozkin的讨论,最好的解决方案是将@Context注释委托给CDI框架(因此,免除CXF的注入工作)。这个建议可能需要JAX-RS规范方面的支持

更简单(临时?)的可能解决方案是使用@Context注入来补充CDI注入(将这项工作委托给CXF,因为它现在可以用于非代理bean和非CDI部署)。这可以通过观察ProcessInjectionTarget事件并提供我们自己的InjectionTarget来实现(这种方法有工作PoC)

关于构造函数注入,似乎CXF不支持将参数传递给提供者构造函数(在CDI的情况下,w/o@Context注释),因此我认为这将是另一个(单独的)问题

有人能帮我指出这个更简单的方法是什么吗

更简单(临时?)的可能解决方案是使用@Context注入来补充CDI注入(将这项工作委托给CXF,因为它现在可以用于非代理bean和非CDI部署)。这可以通过观察ProcessInjectionTarget事件并提供我们自己的InjectionTarget来实现(这种方法有可用的PoC)

或者有没有其他方法可以让Spring框架以正确的方式注入ResourceInfo对象

我已经在我的
applicationContext.xml
中注册了这样的过滤器:

<jaxrs:server id="endpoints">
    <jaxrs:providers>
            <ref bean="authenticationFilter" />
            <ref bean="authorizationFilter" />
        </jaxrs:providers>
    </jaxrs:server>

问题在于注释

可应用于容器请求筛选器的全局绑定注释,指示在实际资源匹配发生之前,应在应用程序中的所有资源上全局应用此类筛选器

该键在“实际资源匹配发生之前”突出显示。因此,即使在资源与请求匹配之前,也会调用过滤器。如果没有匹配的资源,那么就不可能从
ResourceInfo
获取任何信息。如果只删除
@PreMatching
注释,则在找到匹配的资源后将调用筛选器,并且您将能够访问
ResourceInfo

中的所有信息。问题在于注释

可应用于容器请求筛选器的全局绑定注释,指示在实际资源匹配发生之前,应在应用程序中的所有资源上全局应用此类筛选器


该键在“实际资源匹配发生之前”突出显示。因此,即使在资源与请求匹配之前,也会调用过滤器。如果没有匹配的资源,那么就不可能从
ResourceInfo
获取任何信息。如果您只是删除了
@PreMatching
注释,那么在找到匹配的资源后将调用筛选器,并且您将能够访问
ResourceInfo

中的所有信息。您不能在预匹配筛选器中使用ResourceInfo。目前还没有匹配的资源,因此您无法获得有关它的任何信息。您是一名救生员。这解决了我的问题。谢谢。我如何接受它作为正确答案?无法在预匹配筛选器中使用ResourceInfo。目前还没有匹配的资源,因此您无法获得有关它的任何信息。您是一名救生员。这解决了我的问题。谢谢。我如何接受它作为正确答案?