我是 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)中。您需要将范围更广的资源插入到范围更窄的资源中。