In Struts 2 - Where to Put Frequently Used Options Lists

Instead of populating your options lists in Action under populate() method. Put them in application scope, so that lists are not created on each call to an action. This is specially true if your option lists is being used on multiple forms. Such options lists include Countries, Products, Cities, etc.

These rarely change in application life cycle. And if change is required, you can update the application scope object. If we do not use centralized approach, we have to do something like this in our JSP page.
<s:select name="country" list="countries"/>

And in Action class we must define a countries list, like this:

 private List<String> countries;
public List<String> getCountries() {
return countries;
}

public void setCountries() {
countries = new ArrayList<String>();
countries.add("Germany");
countries.add("India");
countries.add("US");
countries.add("Russia");
// ....
}


In execute() or populate() method we must invoke setCountries() to make sure countries are populated before JSP page is called. And if we need the countries list in 10 forms, we must put countries list in 10 Action classes. Big Code Smell.

So here is the solution: Put countries in application scope and make sure its loaded when you application (aka context) is deployed. Let us see how we can do see, step by step:

1. Define an ApplicationListener class.
package com.bitspedia.util;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ApplicationListener implements ServletContextListener {

public void contextInitialized(ServletContextEvent cse) {
List<String> countries = new ArrayList<String>();
countries.add("Germany");
countries.add("India");
countries.put("US");
countries.put("Russia");
ServletContext servletContext = cse.getServletContext();
servletContext.setAttribute("countries", countries);
}

public void contextDestroyed(ServletContextEvent cse) {
}

}
Now we need to tell our container (e.g. Tomcat) that we have defined a new Listener that set the countries list in application scope when context is Initialized. We do so defining a Listener in web.xml file, like this:

2. In web.xml file, add this line:
<listener>
<listener-class>com.bitspedia.util.ApplicationListener</listener-class>
</listener>
So far so good. The last step is to update your JSP page.

3. Change your JSP page like this:
<s:select name="country" list="#application.countries"/>
So in this way you can set as many lists, map or any collection that you need frequently while writing your struts 2 apps. In fact, earlier I used some Util class to achieve this thing, first time I did in a bit professional way. Hope it might help someone else too. Have fun.

Comments