Tuesday, February 12, 2013

Stateless JSF

Just wanted to spread the word: as per Mojarra 2.1.19 / 2.2.0 (both currently only available as snapshot) it's very easy to make the JSF view completely stateless by just setting the transient attribute of the <f:view> to true:


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

That's all. Really. It works for me. The view state isn't been created and thus the session also won't be created when not created yet. This is very useful for e.g. a JSF based login form on the public/stateless side of a website.

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".

A lot of people have been waiting very long for this. See also issue 2731 and this blog of Mojarra developer Manfred Riem.

10 comments:

Rinaldo Pitzer Junior said...

I don't think I get it. Isn't @RequestScoped already "stateless"? How is that different?

Bauke Scholtz said...

It concerns the JSF view state (the JSF component tree state). It's by default stored in the session scope and identified by javax.faces.ViewState hidden input field.

Richard Kennard said...

BalusC,

Love your work!

I haven't used the f:view tag for many years since moving to Facelets. Is there a way to do this without re-introducing it?

If not, where should f:view be placed in order to ensure it preempts any stateful initialization?

Regards,

Richard.

DWuysan said...

Will it work when using f:ajax?

Bauke Scholtz said...

@Richard: just in master template. Assuming that you've XML namespace declarations in <html> tag, then you can put the <f:view> as immediate child, around the <h:head> and <h:body>.

@DWuysan: yes, <f:ajax will keep working, but you can't use a view scoped bean, it would be recreated on every request. You'd need to fiddle with request parameters to maintain state.

gabriel! said...

BalusC you're the man! Thanks so much for this update! Very appreciated. I have two questions for you, firstly, what do you mean we shouldn't use SessionScoped? I thought that was stored in the http session map? How does this affect those beans? Unless you only meant that it would defeat the purpose of stateless jsf.
2nd questions, does this in any way require a change in the way we think about Ajax or partial state validation? Must we take new things into account?
Thanks man!

Thang Pham said...

Hi BalusC. Can you explain a bit on how ajax request would work with stateless mode. So take a case of two selectOneMenu, where the selection of one change the values of the other. In stateful JSF, we have scoped, then upon selection of one selectOneMenu, we update the list of the second selectOneMenu in the backend, then re-render the second list. How do we do that now with JSF stateless, BalusC? pure jQuery?

Liyu Wang said...

It seems that feature broken with AJAX Post redirect, or with RichFaces4.2, If I call with stateless enabled. it called the function, but the rendered result is empty, for example:

Bauke Scholtz said...

@Liyu: it will obviously break where state is required, such as in ajax postbacks which involve conditional renders.

httPants said...

Does the jsf stateless view feature make the omni faces enableRestorableView tag obsolete?