Chris Greenhalgh, 2007-01-29
This document describes the overall structure of an EQUIP2-based web
application, such as this tutorial example.
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 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.
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:
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>
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: