其他 servlet 可以访问 jsf 应用程序中的 cdi bean 吗?
Posted
技术标签:
【中文标题】其他 servlet 可以访问 jsf 应用程序中的 cdi bean 吗?【英文标题】:Can other servlets access cdi beans in jsf application? 【发布时间】:2017-08-18 16:05:03 【问题描述】:我有一个问题可能源于我对 jsf 的理解不足并面临 servlet 概念......我终于让我的 jsf 应用程序在谷歌应用引擎上工作。这花了很多时间和一些解决方法,但它已经启动并运行了:) 现在我想将应用程序中的数据用于 android 应用程序。我想没问题,但当然有……我想我可以在 jsf 应用程序中放置一个额外的 servlet 并访问我用于网页的相同 cdi bean。显然这并不容易。当我尝试将 bean 注入额外的 servlet 时,它们为空。当我为我的 servlet 创建一个额外的 Faces 上下文时,它确实有效!但仅在测试环境中......当我部署到应用程序引擎时,该解决方法不起作用。有什么建议吗?
【问题讨论】:
您有一个带有 EJB 和 WAR 模块的 EAR 文件吗? WAR模块类路径中是否包含EJB模块的jar文件? 【参考方案1】:您可以通过 BeanManager 访问 CDI bean。您可以将其作为资源注入。然后您可以从 BeanManager 获取 bean 实例。这些 bean 非常简单,它们只是返回一个值来查看它们的类型。
CDI bean:
package x;
import java.io.Serializable;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
@Named( value = "myCDIBean" )
@SessionScoped
public class MyCDIBean implements Serializable
private String value = "named";
public MyCDIBean()
public String getValue()
return value;
public void setValue( String value_ )
value = value_;
JSF 托管 bean:
package x;
import java.io.Serializable;
import javax.annotation.ManagedBean;
import javax.enterprise.context.SessionScoped;
@ManagedBean( value = "myJSFManagedBean" )
@SessionScoped
public class MyJSFManagedBean implements Serializable
private String value = "managed";
public MyJSFManagedBean()
public String getValue()
return value;
public void setValue( String value_ )
value = value_;
小服务程序:
package x;
import java.io.IOException;
import java.io.PrintWriter;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.enterprise.context.spi.CreationalContext;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
@WebServlet( urlPatterns ="/MyServlet" )
public class MyServlet extends HttpServlet
@Resource
BeanManager beanManager;
public static <T> T getBeanInstance( BeanManager bm_, Class<T> class_ )
Bean<T> bean = (Bean<T>) bm_.getBeans( class_ ).iterator().next();
CreationalContext<T> ctx = bm_.createCreationalContext( bean );
T object = (T) bm_.getReference(bean, class_, ctx);
return object;
protected void processRequest( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException
response.setContentType( "text/html;charset=UTF-8" );
try (PrintWriter out = response.getWriter())
out.println( "<!DOCTYPE html>" );
out.println( "<html>" );
out.println( "<head>" );
out.println( "<title>Servlet NewServlet</title>" );
out.println( "</head>" );
out.println( "<body>" );
out.println( "<h1>Servlet MyServlet at " + request.getContextPath() + "</h1>" );
MyCDIBean named = getBeanInstance( beanManager, MyCDIBean.class );
out.println( "<p>named bean value: <b>" + named.getValue() + "</b></p>" );
MyJSFManagedBean managed = getBeanInstance( beanManager, MyJSFManagedBean.class );
out.println( "<p>managed bean value: <b>" + managed.getValue() + "</b></p>" );
out.println( "</body>" );
out.println( "</html>" );
【讨论】:
非常感谢您的回答!我学到了很多东西,即使它没有解决我的问题。我无法以任何方式注入或查找 bean 管理器......但问题已解决!当我意识到我需要的每个 bean 都是 requestscoped 时,一个简单的 Bean bean = new Bean() 就足够了。感觉有点尴尬,我把一切都比原来复杂得多...... 不客气! BalusC主页值得一看:jsf.zeef.com/bauke.scholtz#block_24059希望你不介意我推荐它,亲爱的@BalusC :) 永远不要手动实例化企业 bean,因为它的资源不会被初始化(它会创建容器)。始终使用 @EJB/@Inject 注释注入 bean。在这种情况下,具有容器管理生命周期的 bean 将在调用业务方法之前初始化以上是关于其他 servlet 可以访问 jsf 应用程序中的 cdi bean 吗?的主要内容,如果未能解决你的问题,请参考以下文章
Java EE 6:JSF 与 Servlet + JSP。我应该费心学习 JSF 吗?