Save ActionBean fields in session
@Session annotation
@Session annotation is part of Stripes Stuff
- Web site & download: http://sourceforge.net/projects/stripes-stuff/
- View source: http://stripes-stuff.svn.sourceforge.net/viewvc/stripes-stuff/
Purpose
Sometimes it may be more simple to save specific fields in session. It may also take too much memory to save a complete action bean in session.
For this problem, I created a new interceptor which will scan action beans for @Session annotated fields. It will automatically store these fields in session after the event completes and will restore the fields automatically on subsequent requests. When validation error occurs in any phase, fields will not be saved in session as state would normally become inconsistent.
In addition if a request parameter would replace the field, the field will take the value from the request as expected.
Configuration
Simply add org.stripesstuff.plugin.session to extensions packages in web.xml. A common configuration will look like this.
<filter> <display-name>Stripes Filter</display-name> <filter-name>StripesFilter</filter-name> <filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class> <init-param> <param-name>Extension.Packages</param-name> <param-value> org.stripesstuff.plugin.session </param-value> </init-param> </filter>
@Session annotation attributes
Attribute | Value | Default |
---|---|---|
serializable |
| true |
maxTime | Number of minutes before field is removed from session automatically. When 0 or negative, maxTime is considered infinite. | -1 |
key | Key to use to store field in session. This will allow field sharing between different action beans. |
|
If serializable is false and maxTime is negative, field will be removed upon session serialization.
How To
Access objects in session when key is known
Simply use session.getAttribute(key)
.
Remove objects from session
Just calling session.removeAttribute(key) will not work in all cases. SessionStoreInterceptor saves fields in session after event completes and only if no validation error occurs. To remove object from session manually, the best solutions are:
- No validation error: set field to null in the event (if it's not a primitive).
- Validation errors: use
session.removeAttribute(key)
.
Faqs
What is the key under which field is saved?
The key used is the key defined in key attribute of @Session annotation.
When no key attribute is defined, the default key used to store fields is actionBean.getClass() + "#" + field.getName()
.
For instance, if action bean is ca.qc.ircm.web.MyActionBean
and field is myField
, the default key will be "ca.qc.ircm.web.MyActionBean#myField
".
@Session does not work with boolean checkboxes
When a checkbox is checked, a parameter is sent to server. When checkbox is unchecked, nothing is sent to server.
This means that once a @Session annotated checkbox boolean field is checked and the event executes successfully, the boolean field will be true for as long as the field stays in session. Don't use @Session on checkboxes unless you can known that checkbox was unchecked.
Example
Consider this action bean and jsp.
package ca.qc.ircm.stripes.web; import org.stripesstuff.plugin.session.Session; import net.sourceforge.stripes.action.ActionBean; import net.sourceforge.stripes.action.ActionBeanContext; import net.sourceforge.stripes.action.DefaultHandler; import net.sourceforge.stripes.action.ForwardResolution; import net.sourceforge.stripes.action.HandlesEvent; import net.sourceforge.stripes.action.Resolution; /** * Example of Session annotation use. * * @author poitrac */ public class CounterAction implements ActionBean { ActionBeanContext context; public ActionBeanContext getContext() {return context;} public void setContext(ActionBeanContext context) {this.context = context;} /** * Keep track of number of clicks. */ @Session private Integer counter; /** * Number of clicks this submission will represent. */ private Integer amount; /** * Reset counter to 0. * @return Counter page. */ @DefaultHandler public Resolution input() { counter = 0; return new ForwardResolution("index.jsp"); } /** * Add 1 to counter. * @return Counter page. */ @HandlesEvent("count") public Resolution count() { counter++; return new ForwardResolution("index.jsp"); } /** * Add 1 to counter. * @return Counter page. */ @HandlesEvent("countAmount") public Resolution countAmount() { counter += amount; return new ForwardResolution("index.jsp"); } public Integer getCounter() { return counter; } public void setCounter(Integer counter) { this.counter = counter; } public Integer getAmount() { return amount; } public void setAmount(Integer amount) { this.amount = amount; } }
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="s" uri="http://stripes.sourceforge.net/stripes.tld" %> <html> <head> </head> <body> <p>Count: <c:out value="${actionBean.counter}"></c:out></p> <s:form beanclass="ca.qc.ircm.stripes.web.CounterAction" method="POST"> <s:submit name="count">Add 1 to counter</s:submit><br><br> <s:errors field="amount"></s:errors> Enter amount to add to counter: <s:text name="amount" value=""></s:text> <s:submit name="countAmount">Add</s:submit> </s:form> </body> </html>
As you can see, the counter field of CounterAction class has a @Session annotation. This will keep track of the number of clicks made on "count" button. It is also possible to add a specific amount to the counter using countAmount.
Possible attributes to add to @Session annotation
- OverwriteParam. When set, the interceptor will overwrite any modifications made from submitted fields that could modify the field in BindingAndValidation lifecycle.
- SaveOnError. When set, the interceptor will store the value in session even when validation error occurs. Some specific lifecyle could also be specified to limit the lifecycle where stored fields could be overwritten.
Current issues
- None to report for now.
Please report any bugs to me at Christian.Poitras@ircm.qc.ca