繁体   English   中英

在CDI SessionScoped bean中注入HttpServletRequest

[英]Inject HttpServletRequest in CDI SessionScoped bean

我有一个会话范围的CDI bean,我需要以某种方式访问​​此bean的@PostConstruct方法中的HttpServletRequest对象。 可能吗? 我试图注入这样的对象,但结果是:

WELD-001408 Unsatisfied dependencies for type [HttpServletRequest] with qualifiers     [@Default] at injection point [[field] @Inject ...]

据我在谷歌搜索时所了解的,Seam框架具有这样的功能,但是我在GlassFish服务器上有一个标准的Java EE应用程序。

甚至有可能以某种方式将请求传递给CDI bean的@PostConstruct方法吗?

根据您的评论,您想要访问用户主体。 您可以像这样注入它: @Inject Principal principal; @Resource Principal principal; ,请参阅Java EE 6教程

更新资料

我会回答你的直接问题。 在Java EE 7(CDI 1.1)中,开箱即用地支持HttpServletRequest的注入。 但是,在Java EE 6(CDI 1.0)中,现成不支持此功能。 要使其正常运行,请将以下类包含在您的网络应用程序中:

import javax.enterprise.inject.Produces;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class CDIServletRequestProducingListener implements ServletRequestListener {

    private static ThreadLocal<ServletRequest> SERVLET_REQUESTS = new ThreadLocal<>();

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        SERVLET_REQUESTS.set(sre.getServletRequest());
    }

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        SERVLET_REQUESTS.remove();
    }

    @Produces
    private ServletRequest obtain() {
        return SERVLET_REQUESTS.get();
    }

}

注意:仅在GlassFish 3.1.2.2上测试

使用rdcrng中的代码时,请注意以下几点:
*生产者方法obtain是依赖范围的,因此仅对应用程序范围的Bean调用一次(并且将解决除第一个请求以外的所有其他请求的问题)
*您可以使用@RequestScoped解决此问题
*当带注释RequestScoped时,您将仅获得一个代理,因此无法将其级联到HttpServletRequest。 因此,您可能想要HttpServletRequest的生产者。

另请注意:根据CDI规范链接第3.6节,java ee bean不被视为托管bean。 因此,您将获得两个CDIServletRequestProducingListener实例-一个实例由Java EE容器管理,一个实例由CDI容器管理。 它仅适用于SERVLET_REQUESTS是静态的。

为了方便起见,请遵循修改后的代码。

import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;

@WebListener
public class CDIServletRequestProducingListener implements ServletRequestListener {

private static ThreadLocal<ServletRequest> SERVLET_REQUESTS = new ThreadLocal<ServletRequest>();

@Override
public void requestInitialized(ServletRequestEvent sre) {
    SERVLET_REQUESTS.set(sre.getServletRequest());
}

@Override
public void requestDestroyed(ServletRequestEvent sre) {
    SERVLET_REQUESTS.remove();
}

@RequestScoped
@Produces
private HttpServletRequest obtainHttp() {
    ServletRequest servletRequest = SERVLET_REQUESTS.get();
    if (servletRequest instanceof HttpServletRequest) {
        return (HttpServletRequest) servletRequest;
    } else {
        throw new RuntimeException("There is no HttpServletRequest avaible for injection");
    }
}

}

暂无
暂无

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

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