8. Example 06 – The Session
8.1. The concept of a session
When a client browser connects to a web application for the first time, it receives a session token, a unique string of characters that it sends back with every new request it makes to the web application. This allows the web application to recognize the client browser. The web application can then associate data with this session token. This data belongs to a single client browser. Thus, as the client browser makes requests, a memory is built up.
![]() |
As shown above, each user (browser) has its own memory, known as its session. This memory is shared by all requests from the same user. There is also a higher-level memory called application memory. This memory is shared by all requests from all users. It is generally read-only.
8.2. The NetBeans Project
![]() |
The [example-06] project is created by copying the [example-05] project. We will change a few elements to
- take advantage of the user session.
- add a new action [Clear] [1] to clear the input field.
8.3. Configuration
The [struts.xml] file changes as follows:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<!-- internationalization -->
<constant name="struts.custom.i18n.resources" value="messages" />
<!-- default package -->
<package name="default" namespace="/" extends="struts-default">
<default-action-ref name="index" />
<action name="index">
<result type="redirectAction">
<param name="actionName">Enter</param>
<param name="namespace">/actions</param>
</result>
</action>
</package>
<!-- actions package -->
<package name="actions" namespace="/actions" extends="struts-default">
<action name="Enter">
<result name="success">/views/Entry.jsp</result>
</action>
<action name="Confirm" class="actions.Confirm">
<result name="success">/views/Confirmation.jsp</result>
</action>
<action name="Delete" class="actions.Delete">
<result name="success">/views/Entry.jsp</result>
</action>
</package>
</struts>
Lines 27–29 define a new action [Delete] associated with a class [Delete]. The response to this action is the view [Input.jsp].
8.4. The [Confirm] action
It evolves as follows:
package actions;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
public class Confirm extends ActionSupport implements SessionAware{
// model
private String name;
// session
private Map<String, Object> session;
// getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void setSession(Map<String, Object> session) {
this.session = session;
}
@Override
public String execute(){
// Add the name to the session
session.put("name", name);
// navigation
return SUCCESS;
}
}
- Line 7: The [Confirm] class implements the SessionAware interface. This interface has only one method, the setSession method on lines 25–27. Before the execute method is called, one of the request interceptors will inject, via the setSession method, the user’s session in the form of a Map<String, Object> dictionary (line 25). We choose to store this dictionary in the session field on line 12.
- Lines 30–34: the action’s `execute` method. When it executes, the session field has been initialized by one of the interceptors, and the name field by another interceptor. We use this session dictionary to store the name field. Thus, the name will be part of the user’s session and available to all of their requests.
8.5. The [Confirmation.jsp] and [Saisie.jsp] views
The [Confirmation.jsp] view remains unchanged. The [Saisie.jsp] view changes as follows:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><s:text name="saisie.titre1"/></title>
</head>
<body>
<h1><s:text name="saisie.titre2"/></h1>
<s:form action="Confirm">
<s:textfield key="saisie.libelle" name="name" value="%{#attr['name']}"/>
<s:submit key="saisie.valider" action="Confirm"/>
<s:submit key="saisie.effacer" action="Delete"/>
</s:form>
</body>
</html>
- Line 12: We add a `value` attribute to the `<s:textfield>` tag. This attribute sets the value to be displayed in the input field. If this attribute is omitted, `value` defaults to `name`. Here, the value of the attribute is an OGNL (Object-Graph Navigation Language) expression in the form `%{expression_to_evaluate}`. Here, the expression to be evaluated is #attr['name']. The name attribute will be searched for in the current action, the page, the request, the session, and the application, in that order. Since the [Confirm] action places the name attribute in the session, it will be found there. This is shown by the following request:
![]() |
In [1], the entered name was ST. We know that the [Confirm] action placed this name in the session. The link [2] takes us to the URL [3]. The [Saisie.jsp] view is displayed. For the input field, the attribute %{#attr['name']} retrieves the name from the session.
- Line 14: the [Clear] button, which triggers the execution of the [Clear] action and the display of the [Saisie.jsp] view
<action name="Delete" class="actions.Delete">
<result name="success">/vues/Saisie.jsp</result>
</action>
8.6. The [Delete] action
The code for the [Delete] action is as follows:
package actions;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import org.apache.struts2.interceptor.SessionAware;
public class Delete extends ActionSupport implements SessionAware{
// session
private Map<String, Object> session;
@Override
public String execute(){
// retrieve the name from the session
String name = (String) session.get("name");
// remove it from the session if necessary
if(name != null){
session.remove("name");
}
// navigation
return SUCCESS;
}
@Override
public void setSession(Map<String, Object> map) {
this.session = map;
}
}
- Line 7: The [Delete] class implements the [SessionAware] interface, just as the [Confirm] action did.
- line 13: The [Delete] action must clear the contents of the name input field in the [Input.jsp] view. We know that this view retrieves this name from the session. We must therefore remove the name from the session. This is what the execute method does.
Let’s see how this works:
![]() |
In [1], we want to clear the input field. We click the [Clear] button.
<s:submit key="saisie.effacer" action="Effacer"/>
The [Clear] action will be executed. In [2], we notice that the URL called was that of the [Confirm] action. This comes from the <s:form> tag in the form:
<s:form action="Confirm">
which causes the form to be submitted to the [Confirm] action. When the [Clear] button is clicked, the parameter
action:Delete=Delete
was posted to the URL [/actions/Confirm.action]. Struts uses this parameter to process the data posted by the [Delete] action. This action removes the session name. The [Input.jsp] page is the response to the [Delete] action:
<action name="Delete" class="actions.Delete">
<result name="success">/views/Entry.jsp</result>
</action>
This one, which displays the session name, then displays an empty string [3].
We have written several simple examples to introduce important concepts of Struts 2:
- page internationalization
- injection of posted parameters into action fields
- the concept of sessions
- the relationship between Actions and Views
Now that we have mastered these concepts, we are ready to tackle more complex examples. We’ll start by introducing the various tags that can be used in a form.



