Integrating a Web app Framework into Overall app Architecture

Any good web app framework will help us achieve our first goal - a clean web tier. However, this doesn't guarantee that we achieve the second goal - a thin web tier. All three frameworks we've discussed enable us to clean up the web tier, separating presentation and content. However, none gives us much help in integrating our web tier with well-designed architecture. WebWork helps us to create interface-agnostic commands; however, it doesn't provide an infrastructure to enable these commands to invoke business objects in a standard way. Struts enables custom "plug-ins" to be defined in struts-config.xml files, as a way of enabling Struts web components to access other app objects. Plug-ins are configuration wrappers for user-specific app components, and must implement the org.apache.struts.action.PlugIn interface. Struts plug-ins can expose simple bean properties, which can be populated from elements in the struts-config.xml file, as in the following example from the Struts 1.1 sample app:


Population is performed by the Struts Digester. Plug-ins normally set themselves as attributes on the global ServletContext to allow action implementations to access them. However, this is a much less capable and less general approach than the bean-based configuration approach we discussed in the last chapter:

The Java Pet Store sample app (version 1.3), which includes its own web app framework, makes one of the most determined attempts I've seen at achieving a thin web tier, by formalizing the creation of events and the invocation of a centralized event processor (which must implement the com.sun.j2ee.blueprints.waf.controller.web.WebClientController interface). This has the significant advantage that web-tier app code only creates events or commands representing user actions, and displays the result of business processing; framework code (not web -ier app code) invokes business objects to process the events. Unfortunately, this approach, while interesting in theory, isn't workable for real apps. There's a reason successful web app frameworks don't attempt to enforce such prescriptive workflow: it's inflexible and is inappropriate in many cases. Thus we need to use a web app framework in conjunction with an overarching app infrastructure, and the more easily the two integrate, the better off we are.


Since the web interface should be thin, a web app framework should not provide the center of gravity for an app, imposing overall structure. This is the role of the app's business interfaces. A web app framework should merely make it easy to process user input and display the results, and offer easy - interface-based - integration with business objects.

It's possible to integrate the bean-based infrastructure I discussed in the last chapter with any web app framework. The root com.interface21.web.context.WebappContext object, which defines JavaBeans and their relationships without the need to use the Singleton design pattern, is added to a web app's ServletContext by the com.interface21.web.context.ContextLoaderServlet, and can thus be accessed by any object with access to the ServletContext, which includes controllers in any framework. This will provide a superior alternative to using Singleton business objects, or simple factory objects, in any framework. It's achieves as close integration with the web app framework as do Struts plug-ins, despite the fact that they are defined in the Struts configuration file.


Close integration with Struts could easily be achieved by implementing a generic Struts plug-in that created an appContext object - for example, based on a string parameter specifying the location of an XML bean definition file - and added it to the ServletContext. This would enable a Struts configuration file to specify the location of business object bean definitions via a <plug-in> element, and Struts actions to access business objects by looking up the appContext in the ServletContext.

However, with a powerful JavaBeans-based infrastructure, it's not only possible to achieve closer integration of app objects with web app components: it's possible to configure most of the framework itself within the overall app context, meaning that framework components can be transparently configured in exactly the same way as app objects. Such a beans-based infrastructure simplifies both the implementation and the use of a framework.