Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No session generation in jsf

Tags:

jsf

jsf-2

In JSP, there is an attribute session used for disable autogeneration session in a request.

<%@page contentType="text/html" pageEncoding="UTF-8" session="false" %>

Is there any way to do same in JSF2?

Thanks

Why? Because we have a public register form page as a default page in an application. It is a very simple form and session is created everytime people (or robots, etc.) request main page. ManagedBean is RequestScope, but JSF create one session in first navegation request.

like image 321
angelcervera Avatar asked Nov 04 '10 10:11

angelcervera


2 Answers

Just don't use view/session scoped beans (so use only request or application scoped beans) and set state saving to client instead of (default) server by setting the following context parameter in web.xml.

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>

Then JSF won't create the session and will store the view state in a hidden input field with the name javax.faces.ViewState in the form whenever necessary.

The cost of creating and managing the sessions is however pretty negligible. Also, you still have to tradeoff the cost of (de)serializing the view state and the network bandwidth when using client side view state saving.


Update as per your comment:

@BalusC Yes, this could be a global solution. But i need this method only in this public page. In other pages i want server side state saving method.

Ah right. Sorry, I don't see any nice ways in JSF/Facelets to disable the session or change the view state saving on a per-request basis. I'd consider to use a plain HTML <form> instead of a JSF <h:form>, let it submit to another JSF page and make use of @ManagedProperty in the bean associated with the JSF page. E.g.

<form action="register.jsf" method="post">
    <input type="text" name="username" />
    <input type="password" name="password" />
    <input type="submit" />
</form>

with

@ManagedBean
@RequestScoped
public class Register {

    @ManagedProperty(value="#{param.username}")
    private String username;

    @ManagedProperty(value="#{param.password}")
    private String password;

    @PostConstruct
    public void init() {
        // Do your thing here.
        System.out.println("Submitted username/password: " + username + "/" + password);
    }

    // ...
}
like image 176
BalusC Avatar answered Oct 16 '22 21:10

BalusC


Actually answer from BalusC is not correct since Mojarra 2.1.19 / 2.2.0. You can read about this in his blog here. Now fully enough only set:

<f:view transient="true">
   Your regular content
</f:view>

As was said in mentioned post:

The view state isn't been created and thus the session also won't be created when not created yet. [...] Remember to put the associated managed bean in the request scope instead of view/session scope, otherwise you're simply defeating the meaning of the word "stateless".

Next code snippet present in com.sun.faces.application.view.FaceletViewHandlingStrategy class:

        /*
         * Make sure we have a session here if we are using server state
         * saving. The WriteBehindStateWriter needs an active session when
         * it writes out state to a server session.
         * 
         * Note if you flag a view as transient then we won't acquire the
         * session as you are stating it does not need one.
         */
        if (isServerStateSaving() && !viewToRender.isTransient()) {
            getSession(ctx);
        }      

Also be aware that some 3rd-party components libraries, e.g. ICEfaces or other frameworks, e.g. Apache Shiro, could created session by himself for some own purposes.

like image 44
dmaidaniuk Avatar answered Oct 16 '22 20:10

dmaidaniuk