One of the main benefits that the Spring Framework offers is the ability to choose. In a general sense, Spring doesn't force you to use or buy any particular architecture, technology, or methodology (although it certainly has some recommendations regarding one or another). This freedom to choose the architecture, technology or methodology that best suits the developer or his development team is perhaps most evident in the web domain, where Spring offers its own web frameworks (Spring MVC and Spring WebFlux) but at the same time supports integration with a number of popular third-party web frameworks.

General configuration

Before diving into the integration features of each supported web framework, let's first look at the general Spring configuration, which is not specific to any one web framework. (This section applies equally to native variants of the Spring web framework.)

One of the concepts (for lack of a better word) supported by the Spring lightweight application model is layered architecture. Remember that in a "classic" layered architecture, the web tier is just one of many. It serves as one of the entry points into a server-side application and delegates authority to service objects (facades) that are defined at the service layer to handle specific (and presentation-independent) business use cases. In Spring, these are service objects, any other business objects, data access objects, etc. exist in a separate "business context" that does not contain web or presentation tier objects (presentation objects such as Spring MVC controllers are typically configured in a separate "presentation tier context"). This section details how you can configure a Spring container (WebApplicationContext) containing all the "business beans" of your application.

Getting specific, all you need to do is declare ContextLoaderListener in the standard Java EE servlet file web.xml of your web application and add a contextConfigLocationsection (in the same file), which specifies which set of Spring XML configuration files to load.

Consider the following <listener/> configuration:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Next, consider the following configuration <context-param/>:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>

If you do not specify the contextConfigLocation context parameter, the ContextLoaderListener will look for the /WEB-INF/applicationContext.xml file to load. After loading the context files, Spring creates an object WebApplicationContext based on bean definitions and stores it in the ServletContext of the web application.

All Java web frameworks are built on top of the Servlet API, so you can use the following code snippet to access this "business context" ApplicationContext created by the ContextLoaderListener.

The following example shows how to get the WebApplicationContext:

WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

Class WebApplicationContextUtils is for convenience so you don't have to remember the name of the ServletContext attribute. Its getWebApplicationContext() method returns null if the object under the key WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE does not exist. To avoid getting NullPointerExceptions in your application, it is better to use the getRequiredWebApplicationContext() method. This method throws an exception if ApplicationContext is missing.

Once you have a reference to the WebApplicationContext, you can retrieve beans by their name or type. Most developers obtain beans by name and then cast them to one of the implemented interfaces.

Fortunately, most of the frameworks described in this section have easier ways to find beans. Not only do they make it easy to get beans from a Spring container, but they also allow you to use dependency injection in their controllers. Each section of the web framework describes specific integration strategies in more detail.

JSF

JavaServer Faces (JSF) is a standard component-based, event-driven web user interface framework developed as part of the JCP process. It is an official part of the generic Java EE specification, but can also be used separately, for example by embedding Mojarra or MyFaces in Tomcat.

Please note that recent versions of JSF have become tightly coupled with the CDI framework in application servers, and some new JSF features only work in such an environment. JSF support in Spring is no longer actively developed and is mainly used for migration purposes when modernizing older applications based on JSF.

The key element of Spring's integration with JSF is the ELResolver mechanism of the JSF specification.

5.2.1. Spring Bean Recognizer

SpringBeanFacesELResolver is a JSF-compatible implementation of ELResolver that integrates with the standard Unified Expression Language (Unified EL) used in JSF and JSP. It delegates authority first to the Spring "business context" WebApplicationContext and then to the default resolver of the underlying JSF implementation.

From a configuration perspective, you can define SpringBeanFacesELResolver in the faces-context.xml JSF specification file, as shown in the following example:

<faces-config>
    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
        ...
    </application>
</faces-config>

5.2.2. Using FacesContextUtils

Custom ELResolver works great when mapping properties to beans in faces-config.xml, but sometimes you may need to explicitly capture the bean. Class FacesContextUtils makes this task easier. It is similar to WebApplicationContextUtils, except that it accepts a FacesContext parameter rather than a ServletContext.

The following example shows how to use FacesContextUtils:

ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());

Apache Struts 2.x

The Struts framework, created by Craig McClanahan, is an open source project based on the Apache Software Foundation. At the time, it greatly simplified the JSP/Servlet programming paradigm and won over many developers who were using proprietary frameworks. It simplified the programming model, was open source (meaning free), and had a large community, allowing the project to grow and become popular among Java web developers.

As a successor to the original Struts 1.x, check out Struts 2.x and the one provided in Struts a plugin for Spring designed for native integration with Spring.

Apache Tapestry 5.x

Tapestry is “a component-based framework for building dynamic, robust, scalable Java web applications” .

Although Spring has its own powerful web tier, building an enterprise Java application using a combination of Tapestry for the web UI and a Spring container for the lower layers offers a number of unique benefits.

For more information, see the dedicated Tapestry integration module for Spring .

Additional sources

The following links provide additional resources for the various web frameworks discussed in this chapter.