EQUIP2 WebApp Structure Overview

Chris Greenhalgh, 2007-01-29

Introduction

This document describes the overall structure of an EQUIP2-based web application, such as this tutorial example.

Handling an HTTP request

J2EE Container

An EQUIP2-based Web application is a J2EE Servlet-based web application. As such, it runs within a J2EE Servlet container such as Apache Tomcat. The primary purpose of such a container is to handle application-independent aspects of HTTP request handling and to host Java Servlets:
J2EE Container

Like most applications with persistence, a relational database underlies the persistent storage, e.g. a separately configured instance of mySQL, accessed via JDBC.

The Servlet container is capable of hosting multiple web applications; which requests are passed to which web applications is determined by the initial path of the URL requested. For example, the tutorial web application if deployed as initially configured with have path equip2tutorial, and so the container will pass all URLs starting /equip2tutorial/ to that web application.

As with all J2EE Servlet-based web applications, the initial handling of an incoming HTTP request (GET, POST, etc.) is determined by the web application's WEB-INF/web.xml configuration file. In particular, any <servlet-mapping> elements in this document define which URLs which should be handled by which Java Servlets. For example, the standard database forms interface specifies a mapping of URLs (/equip2tutorial)/db/* to the servlet called 'db':

 <servlet-mapping>
    <servlet-name>db</servlet-name>
    <url-pattern>/db/*</url-pattern>
  </servlet-mapping>

The web.xml file also specifies various other J2EE configuration options, including 'Listeners', which are started when the web application as a whole is started.

Spring Framework

The standard WEB-INF/web.xml configuration for an EQUIP2 web application initialised the Log4j logging package and the Spring Framework (via listeners). It also defines any servlets to be created. In particular, any requests to be handled by Spring are mapped to instances of the Spring org.springframework.web.servlet.DispatcherServlet; this includes the .../db/.. URLs mentioned above:
Spring WebApp

Spring has two main kinds of configuration: application-wide, and per-servlet.

Application-wide configuration is specified in the file WEB-INF/applicationContext.xml. In the case of an EQUIP2 web application, this typically creates the persistent dataspace, and any other application-wide classes. Spring configuration files essentially specify that certain Java classes should be instantiated and configured in certain ways - it is a declarative approach to specifying the set of components/classes which comprise a particular application.

Spring Controllers

Per-servlet configuration is specified in files of the form WEB-INF/SERVLETNAME-servlet.xml, for example, WEB-INF/db-servlet.xml for the servlet called 'db'. As well as general classes to be instantiated and linked, the Java beans specified in these servlet-specific files also provide configuration information for the Spring dispatcher servlet itself. In particular, 'handler mapping' beans specify how the dispatcher servlet should map between request URLs and 'controller' objects which are to to handle them:
Application controller layer

For example, consider the following excerpt from db-servlet.xml:

  <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="interceptors">
      <list>
        <ref bean="equipSessionReleaseInterceptor"/>
      </list>
    </property>
   <property name="mappings">
      <props>
        <prop key="/index.htm">filenameViewController</prop>...
     </props>
    </property>
  </bean>

The 'mappings' property here specifies that a request for (/equip2tutorial/db) /index.html should be handled by the controller bean called 'filenameViewController', which must in turn be defined in db-servlet.xml or applicationContext.xml.

In addition, the 'interceptors' property specifies that every single request handled by the provided mappings should first be passed through the 'interceptor' bean 'equipSessionReleaseInterceptor' (in this case, defined in WEB-INF/applicationContext.xml.). This particular interceptor checks at the end of every request that an EQUIP2 session has not been left open; a similar strategy can be used to control access to sets of URLs, e.g. to implement a log-in facility.

A Spring Controller is effectvely a light-weight Servlet, with the additional scaffolding of the Spring Framework. In particular, while a normal Servlet must completely deal with an HTTP request, building and sending the HTTP response, a Spring Controller will often finish by return a Spring ModelAndView object, which the Spring Framework then works out how to render. For example, it may identify (by name) a particular JSP page to be rendered to provide the HTTP response.

This is common structure in Spring Web applications - the Controller itself (written in Java) encapsulates the 'business logic' (including any changes to the database), which the generation of the actual browser page (or whatever the response is).

Spring provides various general-purpose Controllers, some of which can be used directly, and other of which can be subclassed and extended.

The Spring servlet configuration also specifies how abstract (named) views should be mapped to actual view implementations. For example, the following fragment of db-servlet.xml specifies that by default (in this servlet only) named views should be interpreted as identifying JSP files (of the same name) in the WEB-INF/jsp/db directory:

  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
  </bean>

EQUIP2 Dataspace

In an EQUIP2-based Web Application the relational database is not (normally) accessed directly, rather a single persistent EQUIP2 dataspace is used as the persistence API. This is similar to the use of Hibernate in J2EE applications (indeed, the RDBMS-persistent implementation of an EQUIP2 dataspace uses Hibernate). In this kind of persistence, rather than using SQL statements and queries for database access the EQUIP2 API is used; this is a Object-oriented API, i.e. Java objects (generally passive data Java Beans) are put in and fetched from the dataspace:
EQUIP2 Dataspace
Note that as well as the normal Java API, EQUIP2 also has a custom Taglib to facilitate access to the dataspace from Java Server Pages; e.g. see EQUIP2_JSP_Taglib.html from the main EQUIP2 documentation.

Encapsulated Application Logic

In an EQUIP2 web application, at least some of the application-specific logic will be in the Spring Controllers. However, there will also often be common functionality to be shared between controllers. This is typically encapsulated in further Java classes which are created and configured by Spring, and 'wired' to the relevant controllers using Spring bean references:
Encapsulated Application Logic

Other Sources of Activity

In a web application, incoming HTTP requests are perhaps the single most important cause of code execution. However there are ways in which work may be triggered: timers (scheduled tasks), and (in an EQUIP2 application) EQUIP2 notifications.

Scheduled Tasks

Following common Spring web application practice we have been using the Quartz open source Java scheduler to schedule tasks to run in the web application:
Scheduled Tasks
The Spring configuration of Quartz allows particular Java method(s) to be called at defined intervals and/or times, e.g. to handle delated tasks and timeouts.

EQUIP2 Notifications

Unlike Hibernate (or standard relational databases) EQUIP2 has first class support for publish-subscribe notifications of dataspace changes. I.e. one object can register interest in a particular data class (optionally with particular property values), and will then be notified by the dataspace when matching objects are placed into, updated or removed from the dataspace:
EQUIP2 Notifications
These notifications are delivered asynchronously (on a separete notification thread). They can be used to decompose an EQUIP2-based web application into a number of loosely coupled sub-systems. For example, the SMS send/receive subsystem may by implemented to push a certain object class into the dataspace when a message is received; the message handling may then be a separate task which is triggered by notification of such a change (whatever its cause).

Complete Web Application

A complete representative overivew of an EQUIP2 web application is shown below:
Complete Web Application

Changes

2007-01-29