在另一个 Bean 中访问会话作用域 Bean 的最安全方法



我是 jsf 的新手,使用 JSF 2.0 将用户信息保存在会话范围的 Bean 中。我需要在其他豆子上访问此信息以进行繁重的工作。目前,这就是我的做法:-

private UserBean myuser1 = (UserBean)FacesUtils.getManagedBean("UserBean");
and then access properties as 
if (myuser1.getUserType == 1) ...

这有效,但有时会抛出参数错误:参数键为空异常。我也一直在使用以下方法:-

private UserBean myuser2 = new UserBean();
if (myuser2.getUserType == 1) ...

在第二种方法中,我的理解是,如果已经在会话中创建UserBean,则会重试。有很多关于"如何在另一个豆子中访问一个豆子"的问题,所以我很困惑。请告诉我一个干净的方法,它应该始终有效,并且不会突然抛出空指针异常。

我知道最简单的方法是使用@ManagedProperty,我不知道你说的最安全是什么意思。
假设这是您的会话范围 bean :

@ManagedBean
@SessionScopped
public class UserBean {
//bean attributes and methods
}

然后你可以在任何其他 bean 中访问它(前提是它具有相同或更窄的范围)作为这样的属性:

@ManagedBean
@ViewScoped //in this cas you can use SessionScoped, FlowScoped, or RequestScoped too
public class AnotherBean {
@ManagedProperty("#{userBean}")
UserBean userB;
//rest of the bean
//be sure to add getters and setters for the injected bean
}

有关更多详细信息,请查看此内容 希望这有帮助。

实际上, 参数键为空异常:要么你没有初始化对象女巫可以通过添加求解器 对象 = 新对象();在类的构造函数中。

第二个问题可能是对象是"DETACHED",您需要使用方法merge(使用实体管理器)调用对象。

分离的对象是一个已知值,但 JPA 系统不知道它是否是数据库中的最新版本,甚至有时由于某种原因没有设置 id 值(换句话说,不使用 jpa 管理,这可能是您的情况)。

如果 em 是您的实体管理器,并且您具有以下功能:

public Object latestVersion(Object o){ em.merge; }

在你的豆子里有:

@EJB 服务服务;

如果你做em.latestVersion(o);分离对象的问题就解决了。

对于真正的答案:

要从另一个视图访问对象,您只需执行以下操作。

@ManagedBean
@SessionScoped
..... Bean1 {
public static Object o;
.....

}

@ManagedBean
..... Bean 2 {
private Object b=Bean1.o;
.....
}

祝你好运

在另一个作用域 Bean 中设置作用域 Bean 依赖关系的标准做法是使用类似@Inject注释 @Inject 用户豆 用户豆;在要使用的 Bean 中,请使用 UserBean 对象。

你的UserBean应该是一个有状态的。

@Stateful
@LocalBean
public class UserBean
{
private String name;
public String getName() { return name; }
public void setName( String name_ ) { name = name_; }
}

只需将其注入无状态 Bean 即可修改其状态:

@Stateless
@LocalBean
public class MyStatelessBean
{
@EJB
private UserBean userBean;
public String getUserName() { userBean.getName(); };
public void setUserName( String name_ ) { userBean.setName( name_); }
}

或者,您也可以以相同的方式从(不是范围更广的)托管 Bean 访问它:

@ManagedBean
@Dependent
public class MyJSFManagedBean
{
@EJB
private UserBean userBean;
}

您在评论中写道,您根本不使用 EJB。图片修改如下:

UserBean 应该是 SessionScoped CDI Bean

@Named
@SessionScoped
pubilc class UserBean
{}

其他 CDI bean 应该在更近的范围内:

@Named
@Request // or @ViewScoped or @Dependent
public class OwnerBean
{
@Inject
UserBean userBean;
}

容器会自动注意在正确的范围内创建 bean 并将它们插入到 owers(任何类型的容器托管对象:servlet、过滤器、操作侦听器、JSF/CDI bean)中。您需要将范围更广的资源插入到范围更窄的资源中。

最新更新