| More
Java - Page 2
 


Spring MVC Command Beans - As Complex As You Need

By Jim White (Intertech Instructor and Director of Training)

It was Spring Framework training again this past week.  How fitting as it was also the first official week of spring and as pro-baseball's Spring Training was wrapping up.

This week, I had two students in my class that are getting ready to develop a new web application for their company.  This web application is going to be built with Spring and Spring MVC.  They have been given a prior web application as a project "template."  So this week's class gave them a great opportunity to learn Spring, and to figure out how to design and build their application around some of the features they have seen in the existing template project.  I love having students in class that have a very concrete purpose for learning the material.  I found these students are eager to learn, and they like challenging me with interesting problems that they want to apply in their applications.  It provides me the opportunity to do what I call "micro-consulting."  In the span of a class, I can't create an entire application, but I can sometimes help solve particular challenges students have.

One of the complex Spring MVC user interfaces my students, Mark and Senthil, know they will have to address deals with showing multiple records in an HTML table and allowing users to randomly edit the data in the table.  A checked checkbox at the front of each row is an indication, on the part of the user, that they have modified something in that row and want the new data provided in that row stored in the database.  A checkbox left unchecked means that the data in that row, regardless of any changes, to be left unsaved.  For demonstration purposes, I have shown a mock up of this kind of UI below for "customer contact" data.  As the contact data is brought up in the edit page, you can change all the data in each row and each field, but unless you also check the checkbox to the left (arrow identifying below), then no update of that row is made in the database.

image

Now, you can argue the merits of this user interface (I like to call it "table-o-data") all you would like.  However, as a practical matter, we all know that the companies we work with design and evolve user interfaces that the business has become comfortable with or find to be productive.  The question put forth to me was can a Spring MVC controller/command bean design be set up to accommodate such a UI?  The answer is absolutely yes!

Spring's MVC components are quite flexible to address all sorts of imaginable UIs.  The Command bean itself is really just the name we give to the set of objects that harvest and provide data from/to the view (which is usually in the form of HTML).

A More Complex Command Bean

          Note:  Code for this example is provided at the link at the bottom of this blog post.

So let's explore how a more complex command bean can be devised to deal with Mark and Senthil's "table-o-data" UI.  In this case, each row represents a single customer contact.  So, at first we build a simple Contact POJO.

public class Contact {
    private Long id = 0L;
    private String firstName;
    private String lastName;
    private Date dateOfBirth = new Date();
    private boolean married = false;
    private int children;
    private boolean updating = false;
    //getters, setters, constructors left off for brevity
}

The updating boolean property will hold the true/false checkbox indication that the Contact data should be updated/saved in the database.

Most Spring MVC references and books use a simple POJO like this one as the command bean behind a view that allows a user to edit a single instance of a contact.  However, in this case, a collection of these Contact beans must be in place to allow multiple rows to be edited.  To accomplish this task, we need another, more complex, "command bean."  Below is the code for a ContactList that servers as our command bean.  Notice that the ContactList wraps a list of Contact objects from above.

public class ContactList {
    private List<Contact> contacts;
    //getters and setters removed for brevity
}

Command beans do not have to be simple objects with no relationship to other objects.  Command beans can have relationships with other object, can be collections of objects, or even a map of data values (see http://forum.springsource.org/showthread.php?t=18687 for an example of a HashMap of data values captured from a UI).

The JSP - Using Spring Form Tags, JSTL with the Command Bean

The trick of using a more complex command bean is finding out how to access and reference it's properties, associated objects, etc. through the form tags in your JSP.  Spring MVC form tags allow you to use dot notation to access properties containing other objects.  You can also use square brackets [ ] to navigate around collections like our list above.  Here is the form portion of the editcontacts.jsp that displays the many customer contacts in the "table-o-data" example shown above.

<form:form action="editcontacts.request" method="post" commandName="contactList">
    <table border="1">
        <tr>
            <th>&nbsp;</th>
            <th>First name</th>
            <th>Last name</th>
            <th>Date of birth</th>
            <th>Married</th>
            <th>Children</th>
        </tr>
        <c:forEach items="${contactList.contacts}" var="contact" varStatus="x">
            <tr>
                <td><form:checkbox path="contacts[${x.index}].updating" value="true"/></td>
                <td><form:input path="contacts[${x.index}].firstName"/></td>
                <td><form:input path="contacts[${x.index}].lastName"/></td>
                <td><form:input path="contacts[${x.index}].dateOfBirth"/></td>
                <td><form:checkbox path="contacts[${x.index}].married" value="true"/></td>
                <td><form:input path="contacts[${x.index}].children"/></td>
            </tr>
        </c:forEach>
    </table>
    <input type="submit" value="Save" />
    <form:errors path="*"/>
</form:form>

Notice how I use JSTL to iterate through the many Contacts in the ContactList (the command bean) which is stored under the name "contactList."   In the form field tags, I use dot notation in the path attribute to access each contact and the properties within the contact (firstName property is accessed out of a contact bean below).  Using a little expression language and square bracket notation, I can access each Contact in the ContactList list.

path="contacts[${x.index}].firstName"

The Controller

What's left is to show you is the important parts of the controller.  In this example, I use a SimpleFormController and configure the controller's command bean as an instance of ContactList.  The XML Spring configuration of the controller is shown below.

</bean>
    <bean id="editContactController" class="com.intertech.controllers.EditContactController">
    <property name="contactService" ref="contactService" />
    <property name="commandClass" value="com.intertech.domain.ContactList" />
    <property name="commandName" value="contactList" />
    <property name="formView" value="editcontacts" />
    <property name="successView" value="confirm" />
</bean>

In the formBackingObject method of the EditContactController, I retrieve the existing Contacts and create the ContactList to populate the edit contacts JSP.

protected Object formBackingObject(HttpServletRequest request)
        throws Exception {
    List<Contact> contacts = contactService.getContacts();
    ContactList list = new ContactList();
    list.setContacts(contacts);
    return list;
}

Then in the doSubmitAction, when the form holding the "table-o-data" is submitted with a POST operation, simply iterate through each contact in the ContactList command bean and determine if the "updating" check box has been checked.  If so, update the contact in the database.

protected void doSubmitAction(Object command) throws Exception {
    ContactList myList = (ContactList) command;
    for (Contact c : myList.getContacts()) {
        if (c.isUpdating()){
            contactService.updateContact(c);
        }
    }
}

Spring MVC Controller Stereotypes

This example uses the Spring MVC 2.5.6 controller hierarchy.  With Spring 3.0, the controller hierarchy is being retired in favor of stereotype components and @Controller annotations.  However, use of command beans is still used in the new MVC architecture.  So the structure of the command bean and JSP does not change.  The controller becomes just a plain Java class with @Controller and @RequestMapping annotations.

Wrap Up

Command beans can be as complex or as simple as they need to be to capture (and possibly redisplay) data in your UI screens.  Don't limit your imagination to simple classes with primitive properties and Strings.  Understand your UI needs and develop a command bean that addresses the UI and not the reverse.

I'd like to thank my students Mark and Senthil for attending my class this week and for providing the idea for this week's blog entry.  The code for the example you see here (complete with DDL and batch files for HSQLDB) is available in a WAR file (optimized for Apache Tomcat 6) stored in a ZIP file (for transport over the Web) located here.  If you would like to learn more about Spring and be the next student that experiences micro-consulting, join me for a class at Intertech by signing up for Complete Spring Core or Complete Spring Web at Intertech.


Posted by: Jim White
Posted on: 3/29/2010 at 12:34 PM
Tags: ,
Categories: Java | Web Development
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

You Will Live In the Clouds Too!

by Jim White (Instructor and Director of Training)

For the last few months, I have had my head in the clouds.  Go ahead ? insert your favorite one-liner here. My wife has already impaled me with many.  The ?clouds? I speak of are those associated with cloud computing.

If you are in the information technology community and unless you have been living under a rock for the past year or so, I am guessing you have heard about cloud computing.  So, no need to provide a definition then. ? Oops, I can tell from the RCA-dog expression on a lot of reader faces out there that you may not know what cloud computing is!  So you have heard of cloud computing, but your still a little fuzzy on the definition?

This is certainly one of the challenges of cloud computing.  It hasn?t been really well defined yet.  I saw a television commercial a midst the NCAA basketball tournament that touted the benefits of "the cloud."  I'll bet very few people watching really knew what was being advertised.  In fact, even in IT circles the words "cloud computing" are overused to the point that there is no real consensus even where there might be understanding.  The term suffers from something I call illdefinitis:  lacking in clear definition but still used all over the place to sell product, service or other  charms (just like architecture, framework and Web 2.0).  Larry Ellison, in a now famous (or infamous) rant captured on YouTube, skewered cloud computing and called it ?nonsense? and ?water vapor.? While I don?t agree with all of his statements, Mr. Ellison makes a point.  Until cloud computing is well understood and really means something, it won't be taken seriously.  And folks - I am here to tell you, some cloud computing is serious computing!

So with this blog post, I would like to accomplish two goals.  One, try to give you a way to understand cloud computing (I don't want to say define - that might be too ambitious).  Second, I want to try to provide you a reason for exploring cloud computing - at least part of it.

My first task is to provide some help in clarifying what "cloud computing" means.  Cloud computing is about providing information, software and/or computing power as a utility.  How do you get or use electricity or water?  You turn it on when you need it and pay for what you use.  Cloud computing is about turning on and off information and computing "flow" as you need it and paying for what you use.  The problem with cloud computing is that you may need hardware, you many software, you may need all sorts of information or computing flow.  That it why its so hard to label cloud computing and why so many organizations claim to offer cloud computing resources.  Let me provide you with a picture of the general "types" or "categories" of cloud computing.

image

This categorization is being used by many in IT circles today.  You can point to any one (or many together) of the boxes in this diagram and claim "that's cloud computing."

IaaS is the traditional "data center" offered as a pay-for-capacity style of service.  In fact, it is often called a utility service as you order and pay for IaaS like any utility (electricity, water, gas, etc.).  IaaS offers servers, software, data storage, network equipment as virtualized computing power to host your applications and data.  You provide the software/information, the IaaS provider gives you the environment to run it on so that you never touch the hardware.  Flexiscale and GoGrid are two often referenced IaaS providers.

PaaS is IaaS on steroids.  I believe PaaS is the future of computing.  PaaS offers virtualized computing like IaaS.  However, imagine a data center that scales all parts of your hosted environment automatically as your system needs grow.  PaaS also provides a much more sophisticated runtime environment - complete with security, monitoring, testing, and other solutions that typically require tons of application developer time to solve.  PaaS is a utility-styled IaaS hosting environment, but also offers a set of tools and API in support of cloud application development.  These tools help developers address issues of enterprise scale with minimal work.  PaaS is often described as "cloudware" or an operating system for cloud computing as it helps manages all the details of your application beyond the actual business code.

Salesforce.com is the most commonly thought of SaaS.  Microsoft Exchange Online is also thought of as an SaaS.  SaaS is about making packaged commercial software available over the Internet under a subscription or pay-for-usage service.

Now - why should you be looking at cloud computing?  I have been working extensively lately with Microsoft's Windows Azure.  Azure qualifies as one of the PaaS in the diagram above.  I would certainly not call Azure nonsense or water vapor.  In fact, this is a serious platform that I believe will impact nearly all software development in years to come.  We may not all be developing software for this exact Azure cloud computing platform (it is still in its infancy), but we will be developing for a platform like it - whether it be Azure 2.0 (or other future version), IBM's recently announce public cloud service, or other similar PaaS.

Why?  Have you been involved in setting up the development environments, staging environments, runtime environments, and the deployment procedures to get from one environment to the next for a substantially large project?  If you found that task painful and overly time consuming you might want to check out Azure or other PaaS.  If you like designing and building software to help solve business problems, but find thinking about failover, scale, security and other such software issues unappealing, you might want to look at Azure or other PaaS that provides some ready made tools, API and solutions to these common tasks.  If you have ever had the pleasure (tongue firmly planted in cheek) of supporting an application that was about to undergo a challenge in load/scale waiting for the beeper to go off, you need to take a look at how Azure could make life better - much better.  If you have ever had to architect an application that would suffer large loads at certain times but you only had a "normal" load budget for the solution you might want to look into Azure or other PaaS.

Microsoft, IBM, and others are making a big bet on PaaS cloud computing.  Chris Hay and Brian Prince describe Microsoft's work and investment in Azure and Microsoft data centers in support of cloud computing in their book Azure in Action.  I encourage you to explore Chapter 3 of that book, or if you like, take a look at the video on Microsoft's future data centers.  There investment is huge.  Cloud computing in the form of PaaS leaves the details of hardware, operating system, even system architecture, and the other non-business related details of software in the hands of the experts in an economical pay-for-what-you-use form.

I encourage you to take the time to explore cloud computing in all its forms, but particularly PaaS.  I think you'll find that it will soon be time to turn out the lights in our server rooms and data centers and it's time to turn on the cloud computing services.

To learn more about Azure and cloud computing in the Twin Cities area, I invite you to sign up for a free Azure bootcamp offered by Tim Star and I in May.  See here for details.


Posted by: Jim White
Posted on: 3/22/2010 at 12:20 PM
Tags: , , , ,
Categories: Java | Cloud Computing | Cloud Computing
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (1) | Post RSSRSS comment feed

Learn Java RESTful Web Services

It’s St. Patrick's Day week.  May the luck of Irish be with you!  As my father (who was very Irish) used to tell me, everyone is Irish on St. Patty's Day.

Has your company joined the Service Oriented Architecture (SOA) bandwagon?  If so, you have probably become very familiar with the WS-* technologies to include XML, namespaces, Schema, SOAP, WSDL, WS-Security, etc.  I'll call this the "heavy stack" for SOAP-based Web service (service provider) and Web service client (consumer) development.  This stack provides all the standards and technologies for interoperable SOA.  While platform agnostic, many have found SOAP-based Web services difficult to learn and the XML message structure cumbersome and unnecessary for many applications - thus my "heavy" adjective.

As an alternative to SOAP-based Web services, many have started to explore REST-based, or RESTful, Web services.  In fact, many of the familiar Internet giants (Google, Amazon, eBay, Yahoo, etc.) provide RESTful Web services.  Some have abandoned SOAP-based Web services in favor of RESTful services!  Why?  RESTful services are considered "lighter."  That is easier to learn and data exchange that does not have to be as cumbersome/heavy.  RESTful Web services use the conventions that underlie the World Wide Web - namely HTTP - and any data exchange format you would like - to include plain text, CSV, JSON and even XML if you would like.

JAX-RS is the relatively recent Java EE specification and API for dealing with RESTful Web services in Java.  If you would like to learn more about JAX-RS and RESTful Web services, please come join my 2 hour Web seminar on April 15th.  This is a free seminar and is conducted over the Web so you can learn at home or the office (you don't even have to be dressed - just don't share that with me J ).  To sign up for this Web seminar, click the link at the bottom of this post.  If you are looking to learn more about both SOAP and RESTful Web service and Web service client development, consider taking Intertech's Complete Java Web Service class.

Free RESTful Web Services in Java seminar:  http://www.intertech.com/resource/Briefing.aspx?EventID=210


Posted by: Jim White
Posted on: 3/15/2010 at 10:07 AM
Tags: , , , ,
Categories: Java | SOA/Web Services
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Persisting a Class Across Tables with Hibernate

By Jim White (Instructor and Director of Training at Intertech)

Hibernate is a very versatile framework.  Need to persist a Java object into a relational database?  Hibernate provides a way to map the associated Java class's properties to the database table(s) in just about any way you can imagine.  The idea is that the mapping framework should not constrain how you design your database tables or how you design your Java classes.

Pretty regularly, Java objects are often more fine-grained that the database tables that hold their state.  For example, you might have separate Java Customer and Address objects, but have just a single customer table that stores both customer and address data.  This "denormalization" in the database is often done for increased performance or simplicity (see Hibernate's Core documentation on something called components here).

A few weeks ago, I had a couple of students (thanks Anna and Kartik) ask if it was possible to do the opposite.  That is, is it possible to map a single Java class across multiple tables?  Given Hibernate's versatility and flexibility it is probably not unexpected to learn that it is very much possible – although a little more unusual.  Here is an example to show how this is done.

First, here at two tables (Property and Address) which will hold a single object's (RealEstate) state data.

create table address(
id integer GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
street varchar(50),
city varchar(50),
state varchar(50),
zip int
);

create table property(
id integer GENERATED BY DEFAULT AS IDENTITY (START WITH 1) PRIMARY KEY,
square_footage int,
bedrooms int,
bathrooms int,
agent_name varchar(50)
);

 

Now here is the single class to be mapped to these two tables complete with Hibernate mapping annotations to provide the appropriate mapping.

package com.intertech.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.SecondaryTables;
import javax.persistence.Table;

@Entity
@Table(name="Property")
@SecondaryTables({
    @SecondaryTable(name="Address", pkJoinColumns={
        @PrimaryKeyJoinColumn(name="id", referencedColumnName="id")})})
public class RealEstate {
    @Id
    @GeneratedValue()
    private Integer id;
    @Column(table="Address")
    private String street;
    @Column(table="Address")
    private String city;
    @Column(table="Address")
    private String state;
    @Column(table="Address")
    private int zip;
    @Column(name = "square_footage")
    private int squareFootage;
    private int bedrooms;
    private int bathrooms;
    @Column(name = "agent_name")
    private String agentName;

//getters, setters and constructors removed for brevity

}

Importantly, notice the @Table and @SecondaryTables (and @SecondaryTable parameter) annotations that specify the multiple tables to store RealEstate object data.  The id's for both tables must be provided in the @SecondaryTable to indicate how rows in these tables are joined to retrieve the data for any one instance.  Notice also how the properties, like street, that are not stored in the primary table (as identified by the @Table annotation) require the @Column annotation to indicate which secondary table (in this case there is only one – the Address table) holds this state.

If you are interested in this little example code and a small little application that tests storing and retrieving RealEstate objects, you'll find it in a zip file located at Intertech's web site here.

While there are certainly exceptions, if you can dream it you should be able to map it using the Hibernate framework between your Java objects and the relational database.  If you would like to learn more about Hibernate, I would welcome your attendance in our Complete Hibernate class.  Please - come join us!


Posted by: Jim White
Posted on: 3/8/2010 at 12:22 PM
Tags: , ,
Categories: Java
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Nexus OSS hosting - fast and easy

An SMTP Test Server

I am working on a new product for a customer, and it will send a number of emails to users.  I also set up sending emails to the development team for runtime diagnostic information for "those situations".

Of course, we need automated integration tests (ITs), aka functional tests, to prove these email features work.  There are a number of OSS SMTP server products to use, and the key thing is to use one that is fast & easy to setup and teardown in a functional test.

This time I chose SubEtha SMTP, a Java library with a simple email test harness named Wiser.  It's fast, easy, and works well in the functional tests.

Not Current

There was one problem though, the latest SubEtha SMTP version in Maven Central repository was really old, and we encountered a couple of problems that were fixed in more recent versions.  We needed the newest version, and since I have been successfully using Maven for over 5 years, and again on this project, this was important to resolve.

Fix It

I could have simply built SubEtha SMTP and deployed it to my customer's local Maven repo, hosted by Nexus (setup and managed by me!).  But that doesn't solve the real problem.  Since SubEtha SMTP was a pretty good product, I wanted to solve the problem permanently and for others.

Create Maven Build

I planned to create one, but found an existing request in SubEtha's issue tracker to deploy a new release to Maven Central and commented in it.  A discussion ensued; the summary is the SubEtha developers didn't care to use Maven or deal with Maven Central repo updates.  However, they were happy to have me do it for them.  So I created a POM for SubEtha SMTP and committed it.  With a simple command, Maven builds and packages the product into a jar, and also creates jars of the source and JavaDoc.  Almost there?

Host It

The next step was to setup something to get the artifacts to Maven Central.  I've done this before on other OSS products I've worked on, and it involved either a manual upload request (no thanks!) or syncing with a self-made repo on a forge, like SourceForge.  This was ok, but took some extra effort on my part and extra time waiting for it to happen.

Enter Nexus

Recently, Sonatype, the creators of Nexus (a Maven repository manager), began offering free Maven repository hosting for OSS products.  They have a page for the Nexus OSS Repository Hosting info.  Anyone can use/view the Nexus OSS repo, browsing the product repos and their artifacts already setup there.  Additionally, if the build artifacts comply with a number of items, the repo owner can request to have the Nexus OSS repo automatically synced with Maven Central.  Hmmm, sounds perfect.

Having setup Nexus for my current and prior customers (I even used and liked its predecessor, Proximity!), I know what a great product it is.  With the need to get SubEtha SMTP to Maven Central repo, this seemed like the best option - using it as the public repo and auto-syncs to Central.

Couldn't Be Easier

Setting it up was very easy - I just read and followed the information on the Nexus OSS Repo Hosting page.  I created the JIRA ticket requesting the Nexus repo on a Saturday, and Monday morning it was created.  That Monday night, I deployed to the new repo, and then requested the auto-sync to Central.  Approximately 5 hours later, the auto-sync was approved and occurred!  It can't get faster and easier than that! 

Done - D. U. N.

As my wonderful grandfather used to say, "Done, D  U  N"; I have very fond memories of him teasing me with that errant spelling when I was wayyyy too young to understand!  :-)

I reported the successful deploy to Maven Central on the SubEtha SMTP issue, closed it as fixed, and received a couple of thank you's :-).

Thank you Sonatype for creating Nexus and offering this service!  It is fantastic.  I'll move other projects' artifacts to there as well.

P.S.

Interestingly, with the many problems on java.net, especially with the (lack of) support for Maven deployed artifacts there, Sonatype is orchestrating a great effort to help java.net projects migrate their Maven repo hosting to Nexus OSS.  For more information on that, read the Sonatype blog on Java.net Maven Repository Rescue Mission on March 5th.


Posted by: Jeff Jensen
Posted on: 3/1/2010 at 11:34 PM
Tags: , ,
Categories: Java
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed