I am developing a login based application in JSF with primefaces. In that I kept the logged user info in session scoped managedbean and I need to clear that details when he logged out, So How to clear those details which are in SessionScoped ManagedBean object?
You need to invalidate the current session by calling the following function in your action method:
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
Also, as the session scoped beans are trashed buring the subsequent request, be sure to send a redirect:
FacesContext.getCurrentInstance().getExternalContext().redirect("/login.xhtml");
Or, simply return a navigation case outcome from your method:
return "login.xhtml?faces-redirect=true";
In case you don't want to invalidate the session and, effectively, retaining your session scoped beans (which is a bad practice in my opinion), just nullify all of the user data (which was hopefully collected in one session scoped managed bean) in the logout method (you may need to inject that bean in case the logout method resides in another session scoped bean).
You don't need to clear session scoped managed bean manually. Just clear the user session.
By using following code in servlet for logout.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
System_Properties system_Properties=new System_Properties();
PrintWriter out = response.getWriter();
try {
request.getSession().invalidate();
}finally {
out.close();
}
}
If you still manually clear the managed bean data then it can be done by using following code.
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("managed_bean_name", null);
Where "mananged_bean_name" is name of your managed bean.
Hope it helps
When the user logout, the session is destroyed and all the SessionScoped ManagedBean objects too
Related
I have a #SessionScoped CDI bean which is nicely storing information per user session. However I would like to use the same bean but have a new instance of it in say a request scope but once it gets created it remains in the session for that request. So for another request I want it to create a new bean.
Is this possible using CDI?
You'd need a new #RequestScoped bean that creates your existing bean class via the normal new operator (i.e. not injected). You can't simultaneously treat a single bean obtained by the container as request and session scoped.
I tried to develop a simple authentification application based on BaluC's answer in JSF HTTP Session Login, but the problem is that my session scoped bean UserManager is not stored in the user session, so when the LoginFilter checks if the user is logged in,
UserManager userManager=(UserManager)req.getSession().getAttribute("userManager");
it returns null !
Any Idea on how to fix this problem ?
You can try to get it from the context like :
FacesContext context = FacesContext.getCurrentInstance();
UserManager userManager = context.getApplication().evaluateExpressionGet(context, "#{userManager}", UserManager.class);
I am confused about expression language 2 bean-view communication syntax.First of all.Is it possible to have one more managed bean with same name but different scobes.if it is what about accessing them via expression language
on the other hand;
consider there is an attribute in session called DemoBean and there is a session Scobed managed bean called DemoBean as well,
if I try to access this bean via EL like this #{DemoBean} // refers bean or attribute?
they say #{sessionScobe} is the way to access session attributes but
just #{sessionattributename} is valid ? and when I put an object to the session map is it referanced or copied?
JSF's aim is to manage session attributes itself for you. That means you should forget about keeping/recovering session map attributes manually, because you'll be able to do it using JSF's mechanisms.
When you want to keep some info for the whole application, use #ApplicationScoped annotation into your managed bean. You can do the same for sessions, requests or concrete views, using #SessionScoped, #RequestScoped and #ViewScoped annotations.
So, if you want to store some attribute in session:
#ManagedBean
#SessionScoped
public class SessionScopedBean{
public String sessionAttribute;
//Getter and setter
}
You can recover/change the value of the attribute of the bean using the FacesContext:
FacesContext context = FacesContext.getCurrentInstance();
SessionScopedBean bean = (SessionScopedBean) context.getApplication()
.evaluateExpressionGet(context, "#{sessionScopedBean}", SessionScopedBean.class);
bean.setSessionAttribute("value");
Remember JSF beans are by default named with bean's name with the first character lowercased. And remember also this bean will be null at the first hit if you don't initialize yourself. You can do it in an easy way using a PreRenderViewEvent in the bean you want to initialize and executing it for example in your login page. That ensures the bean will keep alive for the rest of the session.
Finally, that's the way you'll access your session attribute from your view:
#{sessionScopedBean.sessionAttribute}
I've tried every solution from a couple dozen google searches: getRequestMap, ElResolver, evaluateExpressionGet and so on. Nothing, absolutely nothing, works. I get null every time. Here is the relevant code:
#ManagedBean(name="readerBean")
#ViewScoped
public class ReaderBean implements Serializable {...
And in the PhaseListener:
public void beforePhase(PhaseEvent event) {
if (event.getPhaseId() == PhaseId.RESTORE_VIEW) {
ReaderBean r = null; //The Managed Bean
try {
FacesContext fctx = FacesContext.getCurrentInstance();
r=(ReaderBean) fctx.getExternalContext().getRequestMap().get("readerBean");
r=(ReaderBean) fctx.getELContext().getELResolver().getValue(fctx.getELContext(), null, "readerBean");
r=(ReaderBean) fctx.getApplication().getExpressionFactory().createValueExpression(fctx.getELContext(), "#{readerBean}", ReaderBean.class).getValue(fctx.getELContext());
r=(ReaderBean) fctx.getApplication().evaluateExpressionGet(fctx, "#{readerBean}", ReaderBean.class);
Nothing works!!!
As to the request map approach, it fails because a view scoped bean is not stored in the request scope. It's instead stored in the view scope. As to the other approaches, they fail because the view scoped bean is stored in the view and thus only available after the view has been restored. However, you're trying to get it before the view has been restored. This is a chicken-egg problem.
You need to revise your approach. Perhaps the bean needs to be a request scoped one? Perhaps the logic needs to be executed at a different phase? Perhaps the logic needs to be performed in the bean itself instead? Etc.
As the concrete functional requirement for which you thought that this is the right solution is unmentioned in the question, I can't point you in the right direction.
I am trying to access session object from within my interceptor by implementing SessionAware interface (I've implemented the setSession method), but I am not able to get my session object this way.
Then I tried ActionContext.getContext().getSession() and I am able to get the session, but I don't know but its coming out to be empty for only the first time in every browser for every user & then it comes filled when another action is invoked.
I assume there is something wrong going with the session. Why is it giving me an empty session only for the first time? Does it set something only after giving empty session for the first time?
If this is the case then everyone will be shown as guest on their first request & then with a username on their 2nd request & hence forth.
Or am I getting the session in the wrong way?
I saw code to get sessions in interceptors, but this does not work for me as it cannot find the constant HTTP_REQUEST.
final ActionContext context = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
HttpSession session = request.getSession(true);
Object user = session.getAttribute(Constants.USER_HANDLE);
Any suggestion on resolving any of the problems?
Something I forgot to mention - my website is a secure site(https), so if the user is not logged in, it would not let him enter the website & if he is logged in, at least his username should be there in the session. Shouldn't it be?
I have an interceptor that also grabs the session as a map. Have you tried something like this? This works for me.
public String intercept( ActionInvocation actionInvocation ) throws Exception {
Map session = actionInvocation.getInvocationContext().getSession();
You can use the following to return the HttpSession -- and create it if it doesn't exist.
HttpSession session = ServletActionContext.getRequest().getSession(true);
If you need the Map instead, then you can just call this right after that last call (since you passed true, the session would have been created and the next call will return a blank session map).
Map<String, Object> session = ActionContext.getContext().getSession();
Alternatively, you can use the CreateSessionInterceptor early in your stack so that the session is created by the time you need it. Then just use the map example above to get it.
FYI: ServletActionContext is a subclass of ActionContext that just has convenience methods for getting the request and response without needing to use the constants like you were trying in your example.
Try this. It worked for me in struts 2.0.14.
public String intercept(ActionInvocation ai) throws Exception {
Map session = ActionContext.getContext().getSession();
You can get the session on Interceptor using ActionContext itself...refer the following code snippet:
SessionMap<String, Object> session = ActionContext.getContext().getSession();
or alternatively you can follow this approach:
The request is available on the ActionContext instance, which is made available via ThreadLocal.
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session = request.getSession(true);
Add the import:
import org.apache.struts2.StrutsStatics;