繁体   English   中英

Spring Jersey在请求范围内的类上注入ContainerRequestContext

[英]Spring Jersey to inject ContainerRequestContext on request scoped class

我已经看了很多帖子,似乎没有什么能像我喜欢的那样正常工作。

我想从过滤器中将一个对象注入ContainerRequestContext属性中,并稍后在其他类中检索它。

这是我的过滤器:

@Priority(Priorities.AUTHENTICATION)
public class AuthorizationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext containerRequestContext) throws IOException {

        containerRequestContext.setProperty("myObject", new Object());
    }
}

这是我要访问ContainerRequestContext的类:

@Provider
public class SessionContextProvider implements ISessionContextProvider {
    @Context
    private ContainerRequestContext request;

    @Override
    public Object getSessionContext() {
        return request.getProperty("mySessionContext");
    }
}

和我的弹簧配置:

@Bean(name="sessionContextProvider")
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public ISessionContextProvider sessionContextProvider() {
    return new SessionContextProvider();
}

如果将ContainerRequestContext注入到我的Web资源中,一切都会按预期进行。 但是,如果调用我的提供程序类,那么ContainerRequestContext始终为null。

我似乎不明白为什么这行不通。

雷格斯·乔纳斯(Reagrds Jonas)

问题在于,通过Jersey / Spring集成,它使我们能够成功地将Spring bean注入到Jersey组件中,但是反之则并非总是如此。

泽西岛拥有自己的DI框架HK2 1 ,它负责处理带有泽西岛组件的注射。 借助Jersey Spring集成,Jersey将查找Spring Bean,并按原样使用它,它不会注入任何依赖项,我想假设Spring应该自己处理注入。

话虽如此,如果您不需要 ISessionContextProvider成为Spring bean,则可以将其设为HK2服务。 很简单 如果您不需要任何特殊的初始化,只需让HK2创建它即可。 这里一个简单的配置

public JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(new AbstractBinder() {
            bind(SessionContextProvider.class)
                    .to(ISessionContextProvider.class)
                    .in(RequestScoped.class);
        });
    }
}

就是这样。 您有一个可注入的ISessionContextProvider 2

如果您需要ISessionContextProvider提供程序作为Spring bean,那么另一种选择是从Spring ApplicatinContext获取bean,并使用HK2的ApplicationContext类似物ServiceLocator自己明确地注入它。 为此,我们需要使用Factory透明地完成所有工作,因此您仍然可以注入Bean,而无需在外部进行任何额外的工作

import javax.inject.Inject;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.ServiceLocator;
import org.springframework.context.ApplicationContext;

public class SessionContextProviderFactory 
        implements Factory<SessionContextProvider> {

    private final ISessionContextProvider provider;

    @Inject
    public SessionContextProviderFactory(ApplicationContext ctx,
                                         ServiceLocator locator) {
        provider = ctx.getBean(ISessionContextProvider.class);
        locator.inject(provider);
    }

    @Override
    public ISessionContextProvider provide() {
        return provider;
    }

    @Override
    public void dispost(ISessionContextProvider provider) { /* noop */ }
}

然后只要注册工厂

public JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(new AbstractBinder() {
            bindFactory(SessionContextProviderFactory.class)
                    .to(ISessionContextProvider.class)
                    .in(RequestScoped.class);
        });
    }
}

1-
2-另请参阅Jersey 2.0的依赖注入

我找到了解决方法。 我可以将Spring HttpServletRequest注入到我的AuthorizationFilter中,并在此上设置SessionContext。

@Autowired
private HttpServletRequest request;

....

request.setAttribute("mySessionContext", sessionContext);

然后,因为HttpServletRequest已知会弹出,并且在我的SessionContextProvider中通常代表相同的事物,所以我这样做:

@Autowired
private HttpServletRequest request;

@Override
public SessionContext getSessionContext() {
    return (SessionContext) request.getAttribute("mySessionContext");
}

我不认为这是最好的解决方案。 但这有效。 如果有更好的解决方案,请等peeskillet输入其他信息。

问候乔纳斯

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM