Persisting to the browser is a common programming paradigm. For example a JSP
page that view or edits a customer almost always has a <input type="hidden"
name="customerId"/> element for storing the customer id. It is common to have
multiple of such elements in a page.

The idea behind this technique is to make the browser as a storage location for
Java objects. In other words, to make the browse as a storage scope, as an
addition to the application/session/request/page scopes that are available for
the JSP and Servlets.

The idea is best shown with an example.

@UrlBinding("/editCustomer.action")
public class CustomerEditActionBean extends BaseActionBean
{
    private static final String VIEW = "/WEB-INF/jsp/editCustomer.jsp";
 
    // jsp parameters
    private Long customerId;
    @PageScope private Customer customer;
     
    @DefaultHandler
    public Resolution loadCustomer()
    {
        customer = customerService.findById(customerId);
        return new ForwardResolution(VIEW);
    }
 
    public Resolution saveChanges()
    {
        customerService.saveOrUpdate(customer);
    }
}
 
public class CustomerService()
{
    public class saveOrUpdate(Customer customer)
    {
        Customer merged = (Customer) customerDao.getSession().merge(customer);
        customerDao.saveOrUpdate(merged);
    }
}
- The loadCustomer() method is the entry point, it loads the customer object and
forward to the EditCustojer.jsp page.
- The @PageScope annotations on the variable customer will serialize it to the
browser.
- saveChanges() is the postback method for saving the customer. The customer
object that was persisted onto the browser will be restored automatically, and
receive the postback parameter bindings as usual. PageScope variables
restoration always happens BEFORE postback parameter bindings.
- Take note of the CustomerService.saveOrUpdate() method. The customer object is
a hibernate managed object obtained in the previous request. The session from
which it was obtained was gone, so we need to use the session.merge() method to
merge it back into the current session.
- Without PageScope, a common paradigm is to load the customer object from the
database before binding so that the postback parameters can be bound to it
directly. This poses a problem if we are using hibernate versioning to guard
against concurrent updates (see 
http://www.intertech.com/Blog/Post/Versioning-Optimistic-Locking-in-Hibernate.aspx).
PageScope solves this problem automatically (as well as saving a database 
fetch).

EditCustomer.jsp
<stripes:form action="/editCustomer.action">
        <stripes:hidden name="_pageScope" value="${_pageScope}"/>
 
        First Name: <stripes:text name="customer.firstName"
value="${actionBean.customer.name}" />
        Last Name: <stripes:text name="customer.lastName"
value="${actionBean.customer.name}" />
        ...
        <stripes:submit name="saveChanges" value="Save Changes" />
    </stripes:form>

- The line <stripes:hidden name="_pageScope" value="${_pageScope}"/> is where
the PageScope is stored. It is an encrypted block of data consisting of the
serialized map of the PageScope objects.
- This line is required for PageScope to work.


------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_sfd2d_oct
_______________________________________________
Stripes-users mailing list
Stripes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/stripes-users

Reply via email to