@Named + @RequestScoped 在 JSF 2.0 和 JBoss 7.1.1 中不起作用
Posted
技术标签:
【中文标题】@Named + @RequestScoped 在 JSF 2.0 和 JBoss 7.1.1 中不起作用【英文标题】:@Named + @RequestScoped not working in JSF 2.0 with JBoss 7.1.1 【发布时间】:2012-06-15 12:07:57 【问题描述】:我有一个可用的@ManagedBean
,我想用@Named + @RequestScoped
bean 替换它。
// Before
@ManagedBean
public class Login
...
// After
import javax.enterprise.context.RequestScoped;
@Named
@RequestScoped
public class Login
...
只要我使用@ManagedBean
,一切正常。 @Named
没有 @RequestScoped
可以工作,但会为每个 EL 表达式创建一个新实例。 @Named + @RequestScoped
但是会产生异常:当请求缓存未激活时,无法添加请求范围的缓存项
java.lang.IllegalStateException: Unable to add request scoped cache item when request cache is not active
at org.jboss.weld.context.cache.RequestScopedBeanCache.addItem(RequestScopedBeanCache.java:51)
at de.prosis.dafe.presentation.Login$Proxy$_$$_WeldClientProxy.getUsername(Login$Proxy$_$$_WeldClientProxy.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:302)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
...
空的beans.xml
确实存在。是否有任何我不知道的陷阱或错误?我敢打赌我错过了一些东西,但它看起来确实像一个错误。我用谷歌搜索了异常消息,但除了引发它的类的来源之外什么也没找到。提前致谢!
更新: 它与我省略的代码有关。登录 bean 尝试在其构造函数中使会话无效,如果它是命名 bean(并非总是如此,如果我向 F5 发送垃圾邮件,它似乎在几次后工作)并作为托管 bean 工作。有人可以解释这种行为吗?
public Login()
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false);
if (session != null)
session.invalidate();
代码来自该教程: http://www.greenkode.com/2011/09/user-authentication-and-authorization-using-jaas-and-servlet-3-0-login/
【问题讨论】:
你的bean必须实现java.io.Serializable
。感谢 BalusC 指出它无法解决问题。尽管如此,bean 还是需要参与 CDI。
@SteveTaylor 您能否提供一些文档,为什么 bean 需要 Serializable 才能参与 CDI?几乎所有@Named
+ @RequestScoped
的示例都不可序列化。谢谢!
对于 RequestScoped 它不需要是可序列化的。
也不知道为什么要在 bean 中执行此操作,似乎过滤器或请求侦听器更适合会话内容。
@LightGuard 很好,这是教程的一部分。我不明白为什么 ManagedBean 有效而 Named 无效,但如果没有会话失效,一切正常。
【参考方案1】:
通过删除构造函数中的会话无效来修复它。我仍然不知道为什么@ManagedBean 有效而@Named 无效。
【讨论】:
自从我意识到真正发生了什么后问题以某种方式发生了变化(sscce ftw ;))并且我无法删除这个问题,我投票赞成关闭。我会接受任何解释为什么@Named
不起作用而 @ManagedBean
起作用的答案。【参考方案2】:
我遇到了同样的问题。从 @ManagedBean (正在工作)切换到 @Named 不起作用。我在 WEB-INF 中有一个 beans.xml 文件,它并没有像大多数人建议的那样解决问题。您可以添加 @Stateless 和 @Named 以使其工作,原因我不知道!如果有人能解释一下,我很想听。
无论如何,我猜测让@Named 工作的“真正”方法是这样的: 如果您导入正确的 @RequestScoped 注释,@Named 将起作用;来自 javax.enterprise.context 包。 javax.faces.bean 包中的@RequestScoped 注释与@Named 注释不兼容。如果您在 @Named 旁边省略了正确的 @RequestScoped,则 bean 将触发,但它不会读取任何属性。
ps。我使用 Glassfish,所以我怀疑这是 JBoss 的问题。
【讨论】:
正如您在我的 Q 中看到的,我使用了正确的 @RequestScoped 注释。不过,这是错误的常见来源。【参考方案3】:我认为您要么在处于these 场景之一中,要么 JBoss AS 7 有另一个问题,例如 this 之一。
顺便说一句,请求范围的 bean 不需要是可序列化的。可能@SteveTaylor 将它与会话范围的 bean 混合在一起。
【讨论】:
是的,只有@SessionScoped
和 @ApplicationScoped
似乎需要可序列化。我试图提供一个 SSCCE,但似乎只要我删除了 jaas 部分,一切都会按预期工作。我会检查的!
一个小的,有效的例子..(短,自包含,正确(可编译),示例)。用谷歌不可能找到:P【参考方案4】:
对于那些仍在与这个问题作斗争的人,这对我有用(原因仍然不明)
我将 GF4 与 netbeans 一起使用。 Netbeans 在 JSF 页面中也有一个很好的 tabcompletion,它与注入的行为不一致。我(目前)只测试了请求范围,但我认为它都在包中..
所以这是我使用的所有组合和结果(在解决方案之上)
最佳解决方案
import javax.faces.bean.RequestScoped;
import javax.inject.Named;
//=> Injection ok - Tab Completion OK
其他较少或不充分的组合(信息)
import javax.faces.bean.RequestScoped;
import javax.annotation.ManagedBean;
//=> Injection ok - Tab Completion NOK
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
//=> Injection nok - Tab Completion OK
import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedBean;
//=> Injection nok - Tab Completion OK
import javax.faces.bean.RequestScoped;
import javax.faces.bean.ManagedBean;
//=> Injection nok - Tab Completion OK
import javax.enterprise.context.RequestScoped;
import javax.annotation.ManagedBean;
//=> Injection nok - Tab Completion NOK
【讨论】:
以上是关于@Named + @RequestScoped 在 JSF 2.0 和 JBoss 7.1.1 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
使用RequestScoped(面孔)和RequestScoped(上下文)有啥区别[重复]
在 JSF 2 的 requestScoped bean 中显式创建会话
无法使用 RequestScoped bean 填充 Select 元素? [复制]
在 WildFly 上重新部署后,CDI 无法在 @Requestscoped REST 服务中将 @Singleton 设置为 @Provider
为啥我会收到 WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped 异常?