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

Jsf 访问另一个bean中的会话作用域bean的最安全方法,jsf,arguments,managed-bean,Jsf,Arguments,Managed Bean,我是jsf新手,使用JSF2.0将用户信息保存在会话范围的bean中。我需要通过其他bean访问这些信息,以便进行繁重的工作。目前,我是这样做的:- private UserBean myuser1 = (UserBean)FacesUtils.getManagedBean("UserBean"); and then access properties as if (myuser1.getUserType == 1) ... 这可以工作,但有时会引发参数错误:参数键为null异常。我也一直在

我是jsf新手,使用JSF2.0将用户信息保存在会话范围的bean中。我需要通过其他bean访问这些信息,以便进行繁重的工作。目前,我是这样做的:-

private UserBean myuser1 = (UserBean)FacesUtils.getManagedBean("UserBean");
and then access properties as 
if (myuser1.getUserType == 1) ...
这可以工作,但有时会引发参数错误:参数键为null异常。我也一直在使用以下方法:-

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

在第二种方法中,我的理解是,若会话中已经创建了UserBean,那个么将重试它。关于“如何在另一个bean中访问一个bean”有很多问题,所以我很困惑。请告诉我一个干净的方法,它应该始终工作,并且不会突然抛出空指针异常。

您的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应该是会话范围的CDIBean

@Named
@SessionScoped
pubilc class UserBean
{}
其他CDIBean应该位于更近的范围内:

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

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

实际上, 参数键为空异常:要么您没有初始化对象,要么通过添加 对象=新对象();//在类的构造函数中

第二个问题可能是对象被“分离”,您需要使用方法merge(使用实体管理器)调用对象

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

如果em是您的实体经理,您具有以下功能:

公共对象最新版本(对象o){em.merge;}

在您的Bean中使用:

@EJB 服务

如果你做em.latestVersion(o);解决了物体分离问题

而真正的答案是:

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

@ManagedBean
@SessionScoped
..... Bean1 {
public static Object o;
.....
}
祝你好运

在另一个作用域bean中设置作用域bean的依赖关系的标准实践是使用@Inject注释,如
@注入UserBean-UserBean;在bean中,您需要使用UserBean对象。

我知道的最简单的方法是使用
@ManagedProperty
,但我不知道您所说的最安全是什么意思。
假设这是您的sessionScoped 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
}
有关更多详细信息,请查看
希望这能有所帮助。

我已经用CDI bean关系扩展了我的答案。@Kukeltje感谢您的提醒,我已经修改了我的答案以包含代码和更多解释。请记住,这是“旧”JSF2方法,建议改用CDI
@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
}