Pages

    Thursday, November 6, 2008

    Spring!

    I'm reading a book right now by Rod Johnson, called "J2EE Design and Development". It's a fabulous book which conveys all kinds of refinements on the architecture of a J2EE application.

    In the book, Johnson puts forth his own novel framework for managing various aspects of the application. This framework became know as Spring and can be found here.

    Of particular interest to me is the MVC framework that can be used to create a thin and clean front end for your web app. After reading a bit about this in the book I went and got Spring and ran through a tutorial that helps you create a non-trivial but simple front end for an inventory system. It's all included in the Spring download, if you're interested.

    So, what are the highlights? First off, anything that can be configured in XML is configured in XML, allowing for dynamic shifting of classes at run-time! Further, one of the big Spring tenants is to program to interfaces (which is simply a sound principal and one I'm finding myself adopting quickly). These two things taken together means that Spring is incredibly non-invasive. You can use the Spring framework without having to write a bunch of code aimed at the Spring framework.

    Let me walk you through a request flow to give you an example of how this works in the MVC framework.

    To start off with, I have set up an index.jsp that redirects to hello.htm so that you can easily enter the application. I've set up a servlet-mapping in my web.xml which intercepts any and all .htm pages and redirects them to the Spring master controller.

    So, enter the Spring master controller (which I use right out of the jar). The master controller will process the request, then hand off the request to a sub-controller which you define. All of this is configured in an XML file as well. I called my application springapp, so I created an XML file called springapp-servlet.xml.

    I have a bean definition in springapp-servlet.xml for /hello.htm:

    <bean name="/hello.htm" class="springapp.web.InventoryController">
    <property name="productManager" ref="productManager"/>
    </bean>

    The master controller sees the class that is attached to /hello.htm and interprets this as the sub-controller which it should forward the request to. So, off the request goes.

    My InventoryController does some logic processing and data gathering (for instance, it gathers a list of items to show in the inventory view) and puts all of this into a model which, in this instance, is a Map which contains a list of Products as well as a Date object. The InventoryController forwards the model and the name of a view back to the master controller and the master controller then forwards the model to the view specified which, in this case, is a jsp called hello.jsp.

    The jsp page loops through the products list (which is model.products) and displays the products.

    We also have a link on hello.jsp which will take us to the price increase page (called priceincrease.jsp). This page allows you to implement a price increase by percentage over all the products.

    Here's where things really get cool. Spring ships with a tag library, called form. It adds on to some normal HTML tags, such as form or input. The specific design, though, is to allow you to map a form or input back to a specific class. So, to enter in the price increase, I use an input defined by the form tag library:

    <form:input path="percentage"/>

    I also define a form which this input sits in:

    <form:form method="post" commandName="priceIncrease">

    The command name maps back to a bean in the springapp-servlet.xml file. That bean has a controller class specified (PriceIncreaseFormController) with it as well as a name (/priceincrease.htm). You see how the pattern is forming up? In that controller, there is a mapping to several things. First off is a mapping which corresponds with the commandName. This is mapped to a class (called PriceIncrease in this instance). PriceIncrease has a field called percentage. So, when the form is submitted, a new object of class PriceIncrease is created with the value in the input attached to the field percentage. PriceIncrease is considered a command, as it provides direction on what the ProductManager should do with the Products.

    Further, a validator is specified for PriceIncrease and is automatically run. All of this is then passed into the PriceIncreaseFormController. The controller evaluates the results of the validator, does any processing necessary, builds a model if necessary, and then forwards everything to a view (which is hello.jsp in this case).

    So, that's the basic workflow. I think it's pretty awesome that so much can be specified in XML. That gives you an amazing amount of flexibility at run-time.

    All in all, I think I'm going to benefit a lot from Spring. It has more than just an MVC component. It provides an abstraction for almost every level of J2EE applications, from the database level (a JDBC abstraction) to a replacement for the EJB tier.

    No comments: