[英]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.