Border
Author: Bruce Grant, Jr. (BX)
Published: January 18, 2010
Simplified Enterprise Java Web Site
An overview of how I made this site
I've been meaning for years to document how I created my web site using enterprise Java tools and design patters but still kept things simple and fast to develop. This article describes the approach I've taken to solving common problems of persistence, separation of cross-cutting concerns, scalability and UI.
I've often joked with my wife that while some men have a beat up old car in front of their house they always mean to work on, I have a web site. This site is never going to be polished and "done" because I use it as my playground to experiment with new technologies and approaches. However, it's been "done" enough to explain what I did in the hope it might benefit someone else.

  1. Creating bxgrant.com
    The following provides a high-level overview of the design decisions that drove the creation of this web site and the software I've chosen to power the web site. Follow-on articles will explain the architecture of the site and the specifics of its implementation.
    1. Design Objectives
      I wanted to create a website that would...

      * Allow me to add new technologies to it over time
      * Support a lot of dynamic data and still perform well
      * Scale by ensuring I could add hardware linearly to the web, application and model architectural tiers independently
      * Ensure encapsulation is achieved by physically isolating each tier of the application from the other tiers
      * Make heavy use of appropriate architectural patterns and design patterns to create a maintainable and extensible code base
    2. Architectural Overview
      Note that all the software I use is indexed in the following section.
      Bruce Grant
      As you can see, from a 10,000 foot view it's pretty vanilla. We've got an Apache web server front-ending a Tomcat application server. Apache forwards requests from a web browser whose URL's match configuration specified in the Apache conf file to Tomcat using the Mod JK connector.

      Tomcat fields the requests flowing through Mod JK and routes them to the correct servlet one way or another. Underneath that servlet is an entire stack of software we'll describe next that comprises the vast bulk of the bxgrant.com application.

      Code in the bxgrant.com application accesses dynamic data stored in the H2 database using JDBC. The bxgrant.com application also accesses the file system where large media objects are stored.

      Bruce Grant
      Inversion of Control & the Control Tier
      Most UI frameworks employee a standard MVC architecture and mine is no different. The purpose of the control tier is to orchestrate the flow of control through the application logic tier and the presentation tier, ensuring that the data from the logic tier is available in a clean way to the presentation tier. You'll remember that one of my design objectives was to ensure the physical isolation of each tier of the application.

      Technically that means that I should not reference any class or library specific to another tier in a given tier. Instead, there should be well defined contracts that are enforced at the boundaries between the tiers, allowing them to communicate with one another. These contracts are expressed as interfaces containing well-defined API's and the various tiers merely reference the interfaces. The implementations of these interfaces remain hidden thanks to Spring.

      Back in the day, architects made heavy use of the Singleton and/or Factory patterns to gain access to an implementation of an interface. Today, most enterprise applications make use of an Inversion of Control container to instantiate the concrete implementations of these interfaces and then inject these instances into the classes that need them using the dependency injection pattern.

      The main servlet of the application, part of the Spring presentation framework, receives requests forwarded from Tomcat and dispatches the request based on the path contained in the URI to a standard Java class, called an Action plain old Java Bean or Action Bean. The URL parameters, whether get or post, are forwarded along to the class and used to initialize the members of the Action Bean.

      The Action Bean does not contain any business logic. Its purpose is to merely fulfill requests made from the browser. Spring injects the Application API object into the Action Beans.

      Application Logic Tier
      The Application API is an interface whose concrete implementation is injected into the Action Bean classes so they can access the business logic of the application. The Application API is itself nothing more than a wrapper around the various services exposed by the application. I have a site service for authentication and session management and such. I have a photo service for the photo application I wrote to manage my family photo's. I have a blog service for the blog software I wrote from scratch. I have a post office service, a file system service and others. These services are injected by Spring into the Application API and then I use the Facade Design Pattern to bring all the service interfaces into a single consistent API for the Action Beans to use. Each Service is comprised of the logic specific to what that service does. Note that the services themselves still do not directly access the database.

      Model / Persistence Tier
      Spring injects a Data Access Object (DAO) interface into the Application Services of the Application Logic tier. These DAO's provide API's that take and return standard Java classes that are eventually persisted to/from the database. The Application Service methods then contain logic and method calls into the DAO API's. This not only free's the application logic developer from having to think about SQL but also about transaction management. I use Spring declarative XML configuration to specify the Services that should have transaction management applied. So, if an exception occurs at any time during the execution of a single Service API method, Spring will cause a rollback to occur for whatever database operations were invoked as a result of calls to the DAO API's. As a result, the application programmer spends her time thinking about the logic and not the details of databases. Also, the actual database in use is irrelevant since its details are completely abstracted from the application, as it should be.

      The concrete DAO implementations themselves are powered by iBatis which performs the actual mapping between Java classes and database queries.

      UI / Presentation Tier
      Once the Action Beans have triggered the right business logic by calling into the Application API and thus have whatever data is required to fulfill the request, the Action Bean forwards the request to one of a few Freemarker page templates. External XML configuration determines which page template to choose based on the URL of the request and other state set on the Action Bean. There are page templates for the various levels of pages in the website as well as Ajax templates, RSS blog templates and so forth. The actual content specific to the request is embedded in the page template via a generic Freemarker invocation to a call to the Action Bean's ID method. The content template is then loaded that matches this ID.

      The Freemarker content template contains very little HTML and mostly Freemarker components representing forms, form fields, dynamic actions, etc. If you haven't yet used a component-based UI framework you really should give it a shot. You'll really learn what code re-use really means. For example, I've got a blog entry component that has a few different rendering facets. I am able to use this same blog entry component for the home page of my site, for the entry-specific page, for the blog entry creation/update page and all by embedding a single component in each of these page content templates.
    3. My Software Recipe

      Language - Java
      Java Developer Site

      More recently I have gotten into scripting languages such as Python, Lua and others. However, I remain fundamentally an enterprise Java guy since that's been my background throughout my career. So, when I began this site more than two years ago I chose Java.

      Database - H2 Database
      H2 Home
      Professionally, I cut my teeth on Sybase and later Oracle. More recently I've done a lot of MySQL and Postgress. However, we moved beyond the database substrate long ago as databases became largely identical technically. As long as a database is small, fast and cheap I no longer think they matter as they once did, especially for personal use.

      I chose H2 specifically because it's lightning fast, has a small memory footprint and yet scales horizontally and vertically due to its clustering capability. It conforms to all the relevant standards and supports the other technologies I care about (Spring, JPA, etc.).

      Web Server - Apache 2
      Apache Server Home

      If I was going to create this web site today, I'd choose the faster and lighter weight Lighty web server which I've been using more recently professionally. However, Apache serves me well enough for my needs. I'm using modjk to have the application server field the dynamic requests. I'm making heavy use of rewrite rules with Mod Rewrite to hide the implementation details of the site and to forward requests to the application server when appropriate. I'm also using Apache's amazing caching technology Mod Disk Cache to serve dynamic documents from cache unless they've changed.

      Application Server - Apache Tomcat
      Tomcat Home

      Again, the boat sailed on differentiation among the application servers quite some time ago. Professionally, I've use JBoss, IBM Websphere, Tomcat and others. The app server vendors have moved up the stack by offering application services on top of their platforms to add value and remain relevant. However, the best of these frameworks run just fine on any application server so once again I don't think the app server you use matters a lot. Pick one that's light weight, that will cluster well and that has a large community. Personally, I'd pick either Tomcat or JBoss but that's me. For my site I chose Tomcat. I would have chosen JBoss but the tools weren't there when I began this site and due to JBoss' complexity you really need good tools.

      Inversion of Control - Spring
      Spring Home

      If you still create software without using Inversion of Control, I don't care what your language is, then it's high time you spend some time to figure it out. Since I'm doing Java I of course chose Spring.

      Persistence Layer - iBatis ORM, Spring ORM/DAO/Tx Management & Apache DBCP
      iBatis Data Mapper ORM
      Spring ORM
      Spring DAO
      Apache DBCP Connection Pool
      Spring Transaction Management

      If you're not familiar with modern approaches to the persistence tier of applications then this list of technologies will seem daunting. Don't worry about it. I'm going to go into it a lot more later. For now understand that modern applications do not hard code SQL statements into their application code. Instead, they rely on Object Relational Mapping libraries to make it easier to interact with databases and more importantly to abstract away the existence of the database since most databases today are nearly interchangeable.

      If I was going to start this project over again today, I'd probably make a single change to the stack of software above. I'd probably go with the Java Persistence API with either Open JPA or https://www.hibernate.org/ which is what I've being doing professionally more recently.

      UI Layer - Freemarker, Stripes & Prototype
      Freemarker Home
      Stripes Home
      Prototype Javascript Framework

      I recently wrote about three Java UI frameworks I've used. For my own site I chose Stripes/Freemarker over JSF. When I began this web site the tools for JSF just weren't there. Also, JSF itself wasn't complete enough - the supported components was incomplete. Today, I'd probably choose JSF. The JBoss team have an excellent component library they've layered on top of JSF called JBoss RichFaces that provides among other things native support for Ajax.

      Freemarker/Stripes is still an excellent choice and I've enjoyed it. Freemarker provides a macro/templating engine allowing you to create components that are ensure the complete separation of model, view and controller. It's simple and it's fast. The only problem I've had with Freemarker is that things can get messy in a hurry if you don't constantly pay attention to what you're doing and follow a component paradigm.

      Stripes is quite possibly the most straight-forward presentation tier framework I've ever used. It enables the mapping of URL's to virtually anything. I'm using it to map to POJO's that provide the model. I then launch freemarker to find the right view template which gets populated from the model class.
Comments
Be the first to add a comment.
Add a Comment
User:
Anonymous (Login or Create Account or Help)
Border