JavaBeans, Introspection, and Contracts
The key problem of building JSP pages in an MVC environment is communication. When a team is divided into a set of individuals that develop Web pages and a second set of individuals that are server-side Java developers, lack of communication can create challenges.
Web developers are aware of what content should appear on the page. They must communicate to the server-side developers that certain dynamic content should be displayed on that page. This dynamic content is generally data that results from a client request (whether successful or unsuccessful). It is also possible for the server-side developer to communicate to the Web developer what dynamic content is available for display at a given point based on the information that has been collected from the user and retrieved from the server.
Formalizing the packaging of the dynamic content represents the contract between the JSP developer and the bean providers. Defining one or more types that expose the dynamic content as properties specifies most of this contract. These types are implemented as JavaBeans. JavaBeans have the advantage of being very tool friendly. It is very easy for a tool to introspect on a JavaBean class (and/or an accompanying BeanInfo class) and present to the developer the available properties, events, and methods. For our Display Page JSPs, these JavaBeans only need to deliver dynamic content as bean properties.
The rest of the contract involves the location of the JavaBeans at runtime. In other words, what information must be supplied in the useBean action, to make it possible to locate the JavaBeans (i.e., in what scope and under what ID will the bean be found).
A typical JSP page development tool feature permits browsing a set of JavaBeans to select a property for display on the page. Complexities arise in dealing with indexed properties—primarily with specifying the context for indexing, and nested properties. Nested properties arise when the structure of the dynamic data is complex. For example, consider our TimeSheet object. This object represents a collection of TimeSheetEntries. A TimeSheetEntry contains properties for date and project, neither of which are primitive data. If one wants to display the project name for a particular TimeSheetEntry, the JSP expression would look like:
<%= TimeSheet.getEntry(index).getProject().getName() %>
This could also be specified by walking the beans and their properties and selecting the leaf property name (TimeSheet, entry(index), project, name). For a tool to facilitate walking nested JavaBean properties, each property must be available in a nontype hiding manner. For instance, in the previous scenario, it is possible to get at the collection of TimeSheetEntries via the method getEntries() on the TimeSheet object. This returns a vector of TimeSheetEntry objects.
A vector, however, hides the type information of its contents. All accessors to the contents of the vector only guarantee that they return an instance of the Object class. A tool will not be able to expose the properties of the actual Java type stored in the collection, only the limited properties of java.lang.Object. By supplying the indexed property entry in the TimeSheet bean, it is possible to perform recursive introspection and make the project name visible to a developer.