webtier@glassfish.java.net

Re: Re: JSF 2.0: View scoped data should be Serializable?

From: Edward Burns <edward.burns_at_oracle.com>
Date: Thu, 19 Jun 2014 08:44:25 -0700

In-Reply-To: <listhandler=26&site=www.java.net&nid=697003&pid=778416&cid=830005&uid=516276&tid=122&1a0ae737d94df71fa75a518601c3189b_at_www.java.net>
References: <listhandler=26&site=www.java.net&nid=697003&pid=778416&cid=830005&uid=516276&tid=122&1a0ae737d94df71fa75a518601c3189b_at_www.java.net>
X-Mailer: VM 8.0.12-devo-585 under 21.4 (patch 22) "Instant Classic" XEmacs Lucid (i386-pc-solaris2.10)
Reply-To: Edward Burns <edward.burns_at_oracle.com>
FCC: ~/fmail/.mail/webtier-sent

>>>>> forums_at_java.net said:

D> Are there any specific guidelines on when and how beans should be
D> serialized? From my understanding, it is recommended for session
D> scoped beans to be serialized for reasons such as to support
D> distributed sessions.

Yes, that is the primary scenario where beans would be serialized.

D> If the application isn't distributed, would session scoped beans
D> still need to be serialized for other reasons?

It's possible that a session scoped bean may somehow find its way into
an ORM system such as JPA that would require serialization.

D> For view scoped beans, the Errata C032 mentions that they "may" need
D> to be serialized. Could you please elaborate on when/why about the
D> scenarios in which serialization would be required so as to help us
D> decide which beans to serialize in our application?

For ViewScoped beans, the case is clearer. Because ViewScoped beans are
stored in a Map that is itself stored in the session, they need to be
Serializable as well.

D> I am confused about how deserialization works. Would JSF lifecycle
D> still take care of initializing the bean; would @PostConstruct
D> annotations still work during deserialization or do we rely on other
D> mechanisms for initialization after deserialization (e.g., no-arg
D> constructor?)

@PostConstruct and @PreDestroy annotated methods should still work
because they are manually invoked by the JSF runtime at the appropriate
time. Consider this example.

This code is taken from the automated regression test at <https://svn.java.net/svn/mojarra~svn/branches/MOJARRA_2_2X_ROLLING/test/servlet30/el>.

SECTION: Class ViewNavigateAwayBean.java

package com.sun.faces.test.servlet30.el;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

/**
 * A ViewScoped bean testing navigate away functionality.
 */
@ManagedBean(name = "viewNavigateAwayBean")
@ViewScoped
public class ViewNavigateAwayBean {

    /**
     * Stores the text.
     */
    private String text;

    /**
     * Constructor.
     */
    public ViewNavigateAwayBean() {
        this.text = "This is from the constructor";
    }

    /**
     * Post-construct.
     *
     */
    @PostConstruct
    public void init() {
        FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().remove("navigatedAway");
        this.text = "This is from the @PostConstruct";
    }

    /**
     * Pre-destroy
     */
    @PreDestroy
    public void destroy() {
        if (FacesContext.getCurrentInstance() != null) {
            FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().put("navigatedAway", true);
        }
    }

    /**
     * Get the text.
     */
    public String getText() {
        return this.text;
    }
}

SECTION: The start page: viewNavigateAway.xhtml

<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Navigate Away Test</title>
    </h:head>
    <h:body>
        <h:form id="form">
            <h:outputText value="#{viewNavigateAwayBean.text}"/>
            <h:commandLink id="submit" action="/viewNavigatedAway" value="Submit"/>
        </h:form>
    </h:body>
</html>


SECTION: The second page: viewNavigatedAway.xhtml

<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Navigated Away Test</title>
    </h:head>
    <h:body>
        <h:outputText value="#{applicationScope['navigatedAway']}"/>
    </h:body>
</html>


SECTION: Explanation

You see that the @PostConstruct annotated method is called when the
start page is viewed. Then, when navigation occurs to the second page,
the @PreDestroy is called.

I hope this helps.

Ed

-- 
| edward.burns_at_oracle.com | office: +1 407 458 0017