【问题标题】:Injecting Beans in JSF 2.0在 JSF 2.0 中注入 Bean
【发布时间】:2013-01-20 21:49:06
【问题描述】:

我有一个 Session 范围的 bean

import javax.faces.bean.SessionScoped;
import javax.inject.Named;
@Named
@SessionScoped
public class SessionBean implements Serializable{

我在一个过滤器中注入对象...

public class FiltroSeguridad implements Filter{

@Inject
private SessionBean sessionBean;

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  HttpServletRequest httpRequest = (HttpServletRequest) request;
  sessionBean.setRutaRedirect(httpRequest.getRequestURI());
}
}

但是,我在下一次交互中注入 SessionBean...

@Model
public class CuentaUsuarioWebBean implements Serializable{
 @Inject
 private SessionBean sessionBean;

public void loginUsuario() throws IOException{
   sessionBean.getRutaRedirect();
}

}

但是属性getRutaRedirect()返回null

我通过 CDI 注释更改导入它仍然不起作用(javax.enterprise.context.SessionScoped),与 JSF 注释相同(javax.faces.bean.ManagedBean@ManagedProperty)。

谢谢。

PD:对不起我的英语!

【问题讨论】:

  • 这只有在你有一个/WEB-INF/beans.xml 文件时才有效(如果你选择了 CDI 方面和/或在一个有点理智的 CDI 教程中已经提到过,这个有点理智的 IDE 已经自动生成了,如果你已阅读教程)。你有这个文件吗?

标签: java jsf-2 dependency-injection javabeans cdi


【解决方案1】:

您不能混合使用 javax.faces.bean.SessionScoped 用于 JSF 和 import javax.inject.Named 用于 CDI 的这两个包的注释。两者都反映了不同的注入机制,不能在同一个 bean 上混合使用。您必须从同一个包中选择两个注释(用于注入和 Bean 范围)。使用相应包中的以下集合

对于基于 CDI 的 bean 定义

javax.enterprise.context.SessionScoped //for bean scoping
javax.inject.Named //for bean declaration
javax.inject.Inject //for injection

对于基于 JSF 的 bean 定义

javax.faces.bean.SessionScoped //for bean scoping
javax.faces.bean.ManagedBean //for bean declaration
javax.faces.bean.ManagedProperty //for bean injection

编辑:现在我更好地理解了您的要求,使用以下构造注入 JSF 托管 bean

 @ManagedProperty(value="#{yourBeanName}")
 SessionBean yourSessionBean;

还请注意,在 JSF 中,您只能注入比其目标范围更广的 bean,例如您可以将 @SessionScoped bean 注入到 @RequestScoped bean 中,而不是相反

但由于 JSF 托管的 bean 已被弃用,最好使用 CDI 托管的。在这种情况下,您可以在更宽范围的 bean 中注入更短范围的 bean

【讨论】:

  • 你好,我试试。但不工作。我用 javax.faces.bean.ManagedBean 导入 javax.faces.bean.SessionScoped。我用 javax.inject.Named 导入 import javax.inject.Named 但是当我设置一个值时 bean 不会改变属性。谢谢。
  • @JuanPabloGómezUribe,您不能将 @Inject 用于 JSF bean。 @inject 仅适用于 CDI 上下文中的 bean。对于 JSF 下的 bean,使用@ManagedProperty。查看更新的答案
  • 您好,感谢您的回复。我使用基于 JSF 的 bean 定义进行证明,并尝试使用 @ManagedProperty(value="#{sessionBean}") 注入 bean SessionBean,但这被注入为 null(bean 已设置和获取)。并且使用 de CDI-Based 有初始问题。谢谢。
  • @JuanPabloGómezUribe 你的环境是什么(JSF 版本和应用服务器)?
  • 嗨,JSF 2.0 和 GlassFish 3.1
【解决方案2】:

忘记托管 bean。它不会以这种方式与过滤器一起使用。如果您坚持使用它,请按照此处提供的答案正确使用:

How implement a login filter in JSF?

现在关于 CDI,如果您的问题是某个特定值为 null,并且您已经通过实际获取 NPE 左右来验证这一点(例如,Eclipse 调试器有时会出错)。然后仔细检查您是否使用了正确的 SessionScoped,如 kolossus 所述,并检查 BalusC 所说的内容 (beans.xml)。

查看 CDI 是否正常工作的一个好方法是向经理索要 bean。将此调试代码放在某处并尝试:

@Inject
BeanManager manager;

@PostConstruct
private void test() {
    Bean<?> bean = (Bean) manager.resolve(manager.getBeans("ANY_NAMED_BEAN_EL_NAME"));
        System.out.println(bean);

}

【讨论】:

  • 您好,谢谢您的回复。我尝试使用How implement a login filter in JSF?
  • 如果你愿意。我自己更喜欢 CDI。
  • 我同意@KarlKildén.. 如果我们有 CDI bean,为什么要使用 JSF 托管 bean
猜你喜欢
  • 1970-01-01
  • 2012-05-22
  • 2013-02-22
  • 1970-01-01
  • 2015-04-15
  • 1970-01-01
  • 2011-05-17
  • 2013-06-25
  • 1970-01-01
相关资源
最近更新 更多