将实体注入 ViewScoped Bean

发布于 2024-11-15 14:49:34 字数 1411 浏览 2 评论 0原文

我是 CDI 新手,希望将其用于 JSF2 应用程序。 MyUser 类是一个简单的 @Entity-Bean,并且在 bean 的 @PostConstruct 方法中创建一个对象:

@Stateful
@Named @javax.faces.bean.SessionScoped
public class UserBean implements Serializable
{
    @Named
    private MyUser user;

    //setter and getter
    //@PostConstruct
}

在 JSF 中访问用户页面的工作方式就像一个魅力:#{user.lastName}。但现在我想从其他 bean 访问此对象,例如在此 @ViewScopedBean 中:

@Named @javax.faces.bean.ViewScoped
public class TestBean implements Serializable
{       
    @Inject private MyUser user;
}

我希望当前(已登录)MyUser user 在其他几个 bean 中可用豆子,但我不知道该怎么做。简单地@Inject是行不通的(而且我很确定这有点简单)。

13:56:22,371 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController]
Error installing to Start: name=vfs:///Applications/Development/
jboss-6.0.0.Final/server/default/deploy/test.ear_WeldBootstrapBean state=Create:
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied
dependencies for type [MyUser] with qualifiers [@Default] at injection
point [[field] @Inject private test.controller.mbean.TestBean.user]

从其他 bean 访问 user 的最佳方法是什么?像 UserBean bean = (UserBean)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("UserBean"); 这样的 JSF1.2 风格代码似乎已经过时了!

I am new to CDI and want to use this for a JSF2 application. The class MyUser is a simple @Entity-Bean and a object is created in a @PostConstruct method in bean:

@Stateful
@Named @javax.faces.bean.SessionScoped
public class UserBean implements Serializable
{
    @Named
    private MyUser user;

    //setter and getter
    //@PostConstruct
}

Accessing the user in a JSF pages works like a charm: #{user.lastName}. But now I want to access this object from other beans, e.g. in this @ViewScopedBean:

@Named @javax.faces.bean.ViewScoped
public class TestBean implements Serializable
{       
    @Inject private MyUser user;
}

I want the current (logged in) MyUser user to be available in a couple of other beans, but I'm not sure how to do this. Simply @Injecting it did not work (and I'm pretty sure this would be a litte bit to simple).

13:56:22,371 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController]
Error installing to Start: name=vfs:///Applications/Development/
jboss-6.0.0.Final/server/default/deploy/test.ear_WeldBootstrapBean state=Create:
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied
dependencies for type [MyUser] with qualifiers [@Default] at injection
point [[field] @Inject private test.controller.mbean.TestBean.user]

What is the best approach to access the user from other beans? JSF1.2 style code like UserBean bean = (UserBean)FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("UserBean"); seems seems to be old fashioned!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只等公子 2024-11-22 14:49:34

首先:您不想直接注入实体。实体由 ORM 框架相当独立地控制,并且有自己的生命周期。不要将它们用作托管 Bean。

根据这个定义,JPA
实体受到技术管理
豆子。然而,实体有其
拥有特殊的生命周期、状态和
身份模型通常是
通过 JPA 或使用 new 实例化。
因此我们不直接推荐
注入实体类。我们
特别建议不要分配
@Dependent 以外的范围
实体类,因为 JPA 无法
持久注入 CDI 代理。

有关详细信息,请参阅此处

回答你的问题:你不能“排除”类似(经过身份验证的)用户的东西,即使这在 Seam 2 中是可能的,但 CDI 的整个代理机制不再允许这样做。您需要做的是:

  • 编写一个处理身份验证的托管 bean 并将其放入正确的范围(可能是会话范围)。
  • 如果登录成功,则使用此 bean 的属性来存储经过身份验证的用户。
  • 使用生产者方法(可能带有像 @LoggedIn 这样的限定符)使用户在您的应用程序中可用

像这样注入用户:

@Inject
@LoggedIn
private User user

这就是 CDI 方式;-)

First of all: You don't want to directly inject entities. Entities are pretty independently controlled by the ORM-framework, and have their own life cycle. Don't use them as managed beans.

According to this definition, JPA
entities are technically managed
beans. However, entities have their
own special lifecycle, state and
identity model and are usually
instantiated by JPA or using new.
Therefore we don't recommend directly
injecting an entity class. We
especially recommend against assigning
a scope other than @Dependent to an
entity class, since JPA is not able to
persist injected CDI proxies.

See here for details.

To answer your question: You cannot "outject" something like an (authenticated) user, even though this was possible in Seam 2, the whole proxy mechanism of CDI doesn't allow this anymore. What you need to do is the following:

  • Write a managed bean which handles the authentication and put it in the correct scope (probably session scope).
  • If login succeeds, use an attribute of this bean to store the authenticated user.
  • Use a producer method (probably with a qualifier like @LoggedIn) to make the user availabe in your application

Inject the user like this:

@Inject
@LoggedIn
private User user

That's the CDI-way ;-)

Hello爱情风 2024-11-22 14:49:34

@Inject ed bean 也是 @Named bean 吗?

如果是,则 MyUser bean 的范围是否小于 TestBean。请记住,@ViewScoped bean 的托管属性必须是 @ViewScoped、@SessionScoped 或 @ApplicationScoped

Is the @Inject ed bean a @Named bean, too?

If it is, has the MyUser bean a lesser scope than the TestBean. Remember that a @ViewScoped bean's managed properties have to be @ViewScoped, @SessionScoped or @ApplicationScoped

池木 2024-11-22 14:49:34

CDI 未指定 @ViewScoped 注释。这是 JSF2 注释。唯一允许的注释是:@RequestScoped@SessionScoped@ApplicationScoped@Dependent@ConversationScoped。前三个是 CDI 唯一允许的 JSF 范围。

如果您需要支持@ViewScope注释,您需要自己编写。幸运的是,其他人已经做到了这之前

CDI does not specify a @ViewScoped annotation. This is a JSF2 annotation. The only possible annotations allowed are : @RequestScoped, @SessionScoped, @ApplicationScoped, @Dependent and @ConversationScoped. The first three are the only JSF scopes allowed by CDI.

If you need to support the @ViewScope annotation, you'll need write it yourself. Luckily, someone else has done this before.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文