This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I am using a ContextListener to build a list containing domain objects during the application's context initialization.
Now I want to display this list (which represents DB table rows) in the first page that renders.
I have assigned this list to the Servlet Context and I have referenced this context in my page like this:
FacesContext fc = FacesContext.getCurrentInstance();
ServletContext sc = (ServletContext) fc.getExternalContext().getContext();
List patients = sc.getAttribute("PATIENT_LIST");
The PATIENT_LIST attribute is set in the context listener.
First, is this a sensible way to initialize such a list in a JSF environment?
Second, because I have not used a backing bean to hold the list, how do I use the JSF tags such as <h:dataTable...> to render the contents of this list?
(Using JSTL for this is easy but I need to use JSF tags.)
Afterthought, perhaps I should implement a backing bean and assign the list to that bean during initialization and dispense with the Servlet Context approach.
JSF Rule #1: The more javax.faces code in the bean, the more likely you're doing it wrong.
If you have an application scope bean and you want to display it in a datatable, the simplest way to do that is to construct a backing bean and inject the application-scope bean into it using the managed-property element of the faces-config.xml file. No javax.faces code is required - just setter/getter methods in the backing bean.
You can't present the applicaition-scope object directly to the view no matter which method you use to gain access to it, however - the dataTable controller requires additional model information to support its ability to iterate and to reference rows within the dataTable view. That means you need a javax.faces.Datamodel object to serve as the fronting object. The DataModel and its sibling the SelectItem are the only 2 javax.faces classes many JSF apps really need. There is a time and a place for more involved mechanisms, but most people overuse them and the result is lower productivity and code which has a lower level of reusability and maintainability.
You mentioned being unsure of how to initialize the app-scope object. You can initialize it as a JSF-scope managed bean, you can construct it in a start-time servlet method, you can use Spring. It's mostly a matter of what works best for you.
An IDE is no substitute for an Intelligent Developer.