簡體   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