Wiring Your Web Application with Open Source Java

Building non-trivial web applications with Java is no trivial task. There are many things to consider when
structuring an architecture to house an application. From a high-level, developers are faced with
decisions about how they are going to construct user interfaces, where the business logic will
reside, and how to persist application data. Each of these three layers has their
own questions to be answered. What technologies should be implemented across each layer? How can
the application be designed so that it is loosely coupled and flexible to change? Does the architecture
allow layers to be replaced without affecting other layers? How will the application handle container
level services such as transactions?

There are definitely a number of questions that need to be addressed when creating an architecture for your
web application. Fortunately, there have been developers that have run into these reoccurring problems
and built frameworks to address these issues. A good framework relieves developers from attempting to
reinvent the wheel for complex problems; it is extensible for internal customization; and it has a strong user
community to support it. Frameworks generally address one problem well. However, your application will have
several layers that might require their own framework. Just solving your UI problem does not mean that you should
couple your business logic and persistence logic into a UI component. For example, you should not have business
logic with JDBC code inside of a controller. This is not the functionality that a controller was intended to
provide. A UI controller should be a lightweight component that delegates calls to other application layers for
services outside the UI scope. Good frameworks naturally form guidelines where code should be placed. More
importantly, frameworks alleviate developers from building code such as persistence from scratch and allow them
to concentrate on the application logic that is important to a client.

This article will discuss how to combine several well-known frameworks to achieve loose coupling, how to
structure your architecture, and how to enforce a consistent design across all application layers. The challenge
is combining frameworks so that each layer is exposed to each other in a loosely coupled manner, regardless of
the underlying technologies. This article will discuss one strategy for combining frameworks using three popular
open source frameworks. For the presentation layer we will use Struts;
for our business layer we will use Spring; and for our persistence
layer we will use Hibernate. You should be able to substitute any one of
these frameworks in your application and get the same effect. Figure 1 shows what this looks like from a high
level when the frameworks are combined.

Application Layering

Most non-trivial web applications can be divided into at least four layers of responsibility. These layers are
the presentation, persistence, business, and domain model layers. Each layer has a distinct responsibility in the
application and should not mix functionality with other layers. Each application layer should be isolated from other
layers but allow an interface for communication between them. Let's start by inspecting each of these layers and
discuss what these layers should provide and what they should not provide.

The Presentation Layer

At one end of a typical web application is the presentation layer. Many Java developers understand what
Struts provides. However, too often, coupled code such as business logic is placed into an
org.apache.struts.Action. So, let's agree on what a framework like Struts should provide. Here is
what Struts is responsible for:

Managing requests and responses for a user.

Providing a controller to delegate calls to business logic and other upstream processes.

Handling exceptions from other tiers that throw exceptions to a Struts Action.

Assembling a model that can be presented in a view.

Performing UI validation.

Here are some items that are often coded using Struts but should not be associated with the presentation layer:

Direct communication with the database, such as JDBC calls.

Business logic and validation related to your application.

Transaction management.

Introducing this type of code in the presentation layer leads to type coupling and cumbersome maintenance.

The Persistence Layer

At the other end of a typical web application is the persistence layer. This is usually where things get out of
control fast. Developers underestimate the challenges in building their own persistence frameworks. A custom,
in-house persistence layer not only requires a great amount of development time, but also often lacks functionality
and becomes unmanageable. There are several open source object-to-relational mapping (ORM) frameworks that solve
much of this problem. In particular, the Hibernate framework allows object-to-relational persistence and query
service for Java. Hibernate has a medium learning curve for Java developers who are already familiar with SQL and
the JDBC API. Hibernate persistent objects are based on plain-old Java objects and Java collections. Furthermore,
using Hibernate does not interfere with your IDE. The following list contains the type of code that you would
write inside a persistence framework:

Querying relational information into objects. Hibernate does this through an OO query language called HQL, or
by using an expressive criteria API. HQL is very similar to SQL except you use objects instead of tables and
fields instead of columns. There are some new specific HQL language elements to learn; however, they are easy
to understand and well documented. HQL is a natural language to use for querying objects that require
a small learning curve.

Saving, updating, and deleting information stored in a database.

Advanced object-to-relational mapping frameworks like Hibernate have support for most major SQL
databases, and they support parent/child relationships, transactions, inheritance, and polymorphism.

Here are some items that should be avoided in the persistence layer:

Business logic should be in a higher layer of your application. Only data access operations should be permitted.

You should not have persistence logic coupled with your presentation logic. Avoid logic in presentation components
such as JSPs or servlet-based classes that communicate with data access directly. By isolating persistence logic into
its own layer, the application becomes flexible to change without affecting code in other layers. For example, Hibernate
could be replaced with another persistence framework or API without modification to the code in any other layer.

The Business Layer

The middle component of a typical web application is the business or service layer. This service layer is often
the most ignored layer from a coding perspective. It is not uncommon to find this type of code scattered around in
the UI layer or in the persistence layer. This is not the correct place because it leads to tightly coupled applications
and code that can be hard to maintain over time. Fortunately, several frameworks exist that address these issues. Two
of the most popular frameworks in this space are Spring and PicoContainer. These are referred to as microcontainers that
have a very small footprint and determine how you wire your objects together. Both of these frameworks work on a simple
concept of dependency injection (also known as inversion of control). This article will focus on Spring's use of setter
injection through bean properties for named configuration parameters. Spring also allows a sophisticated form of
constructor injection as an alternative to setter injection as well. The objects are wired together by a simple XML file
that contains references to objects such as the transaction management handler, object factories,
service objects that contain business logic, and data access objects (DAO).

The way Spring uses these concepts will be made clearer with examples later in this article. The business layer should
be responsible for the following:

Handling application business logic and business validation

Managing transactions

Allowing interfaces for interaction with other layers

Managing dependencies between business level objects

Adding flexibility between the presentation and the persistence layer so they do not directly communicate
with each other

Exposing a context to the business layer from the presentation layer to obtain business services

Managing implementations from the business logic to the persistence layer

The Domain Model Layer

Finally, since we are addressing non-trivial, web-based applications we need a set of objects that can move between the
different layers. The domain object layer consists of objects that represent real-world business objects such as an
Order, OrderLineItem, Product, and so on. This layer allows developers to stop
building and maintaining unnecessary data transfer objects, or DTOs, to match their domain objects. For example, Hibernate
allows you to read database information into an object graph of domain objects, so that you can present it to your UI layer
in a disconnected manner. Those objects can be updated and sent back across to the persistence layer and updated within
the database. Furthermore, you do not have to transform objects into DTOs, which can get lost in translation as they are
moved between different application layers. This model allows Java developers to work with objects naturally in an OO fashion
without additional coding.