我需要在我的JSF应用程序的会话范围中只保留一个对象。我在哪里定义会话变量,如何从视图文件或辅助bean中获取和设置它?
答案 0 :(得分:29)
有几种方法:
使用ExternalContext#getSessionMap()
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
Map<String, Object> sessionMap = externalContext.getSessionMap();
sessionMap.put("somekey", yourVariable);
然后是:
SomeObject yourVariable = (SomeObject) sessionMap.get("somekey");
或者,将它作为会话范围bean的属性,将其注入请求范围的bean中。
sessionBean.setSomeVariable(yourVariable);
然后是:
SomeObject yourVariable = sessionBean.getSomeVariable();
如here所描述的faces-config.xml
或者你已经使用JSF 2.0,@ManagedProperty
@ManagedBean
@RequestScoped
public class RequestBean {
@ManagedProperty("#{sessionBean}")
private SessionBean sessionBean;
// ...
}
与
@ManagedBean
@SessionScoped
public class SessionBean {
private SomeObject someVariable;
// ...
}
答案 1 :(得分:2)
Just moving along to JSF 2.2 and CDI 1.2 - Injection will at least be simpler. Keeping in line with the original answer of @BalusC:
import javax.enterprise.context.RequestScoped;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
@Named
@RequestScoped
public class RequestBean {
@Inject
private SessionBean sessionBean;
// ...
@PostConstruct
void init() {
// Interact with sessionBean during construction
// but after Injection.
}
}
with
import java.io.Serializable;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
@Named
@SessionScoped
public class SessionBean implements Serializable {
private SomeObject someVariable;
// ...
}
There are several important notes to be made - particularly the switch to @Named
, and the Fully Qualified Package Name for RequestScoped
and SessionScoped
. Also for making a Class SessionScoped
it should also be made Serializable
.
The addition of @Inject
makes it really simple - but understand that the injected sessionBean
object is only available after construction, not during. This means you do not have access to sessionBean
within the constructor of RequestBean
. This is solved by the use of @PostConstruct
which gets triggered after injection is complete, and RequestBean
is otherwise fully initialized.
答案 2 :(得分:0)
当您调用方法FacesContext.getCurrentInstance()
时,它将返回当前线程,但是在P.S.V.M的情况下,将不会在应用程序上下文中运行线程。所以你得到了NPE。
更好地使用这样的东西:
public String checker() {
SessionFactory factory = HibernateUtil.getSessionFactory();
Session session = factory.getCurrentSession();
session.beginTransaction();
Query q = session.createQuery("from UserLogin where UserId='"
+ uid.getUserId() + "'and Pswd='" + uid.getPswd()
+ "'and RoleId='" + uid.getRoleId() + "'");
setUid((UserLogin) q.uniqueResult());
System.out.println("upto here every thing is workind properly");
if (uid != null) {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequestrequest = (HttpServletRequest) context
.getExternalContext().getRequest();
HttpSession appsession = request.getSession(true);
if (appsession.isNew() == false) {
appsession.invalidate();
appsession = request.getSession(true);
}
context.getExternalContext().getSessionMap().put("userbean", uid);
session.close();
return uid.getRoleId();
} else
return "invalid";
}
并将其放入会话bean中。您可以使用该代码验证用户。