Friday 7 June 2013

How-To #1: Basic Spring 3 MVC Tutorial



This is a very basic How-To for Spring 3 MVC - this will give you a Dispatcher Servlet that will forward a request to 'carmatch/home' to a Controller, which will present a specific JSP page to the user. All of this is achieved with the minimum amount of configuration, code or hassle. This is a very simple example of why you should be using Spring in your Java applications.

To make this work you'll need the following JAR files available on your classpath:

Spring-core
Spring-web
Spring-webmvc
Spring-expression
Spring-beans
Spring-context
commons-logging

The more important part of getting Spring MVC up-and-running is declaring the DispatcherServlet in your web.xml deployment descriptor. This will load the DispatcherServlet when your application loads up for the first time in the container.

web.xml


  Car Match Web

  
   mvc-dispatcher
        
         org.springframework.web.servlet.DispatcherServlet
        
        1
  
 
  
  mvc-dispatcher
    /
   




This is very straight forward - a single Servlet is defined, instantiating a new Spring MVC Dispatcher Servlet. This is mapped to all URLs (the url-pattern defined in the servlet-mapping tag), so any access to your application will be serviced by the Dispatcher Servlet. Note the name of the servlet (mvc-dispatcher). By default, Spring expects us to have a Spring configuration file named the same as the servlet with "-servlet.xml' on the end. So in this case, our configuration file is called:

 mvc-dispatcher-servlet.xml

        
     
 
    
        
            /WEB-INF/jsp/
        
        
            .jsp
        
    



Another reasonably simple configuration file, right? The first part (context:component-scan) says that we want to automatically scan Java classes in that package (and all sub-packages) for Spring-enabled Java classes. We could define these manually in this file, but it's much cleaner and easier to do this in the Java class itself - more on this in a bit. The second part of this file, the 'viewResolver' is all about mapping from a request (so a user requesting 'carmatch/home') to a resource (a specific jsp / html page). All this is saying is that when we get a request that goes through the dispatcher servlet, the required resource can be found at /WEB-INF/jsp/.JSP. So if we requested the homepage, we would receieve 'WEB-INF/jsp/home.jsp'. You might be wondering where we get the 'home' part of that from - that's where the Controller comes in...

HomepageController.java
package com.ratech.carmatch.web.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("home")
public class HomepageController {
 
  @RequestMapping(method = RequestMethod.GET)
  public String getHomepage() {   
    return "home";
  }
  
}

Again, this is a very simple file. A lot is done for us automatically by declaring a very small amount of special configuration. Here we declare the @Controller annotation. This is picked up by the 'component-scan' bit of configuration in our mvc-dispatcher-servlet.xml file - and creates a Spring Bean that is available to our application for handling resource requests.

In this case we also declare a @RequestMapping annotation - this simply defines exactly what type of request we are interested in - here we are interested in GET requests to 'home'. If we get a request that fulfils these criteria, we return "home". Remember our 'viewResolver' in the Spring configuration file? This will add 'home' into the rest the stuff we defined there to get 'WEB-INF/jsp/home.jsp'. This means that GET requests to /home will result in the home.jsp page being presented to the user.

The real benefit here is that we've not put any more detail than necessary in our Java class. Imagine we want to move ALL our jsps out of the JSP folder and into a 'pages' folder - if we've hard-coded these JSP addresses in our Java, we have to update and re-compile dozens of classes. If it's in a single place in the configuration, we have to do a one-line configuration change, and the Java stays the same. A perfect example of the power of Spring.

And this will just work - the basic framework I've provided here will expand as far as necessary, it has all the essential parts, and there is endless scope for adding complexity and clever touches.

Java Deployment Descriptor: web.xml

When deploying a Java web application, arguably the single most important file is the deployment descriptor. It's sole purpose is to describe to the container (the server you're deploying your application on e.g. Tomcat, JBoss, Websphere..) exactly how to deploy the application. It defines a bunch of core information on how your application will be accessed by users.

 The following is the most basic valid web.xml file for a Servlet 3.0 J2EE Web Application.




        3.0 WebApp


We can extend this by adding a 'welcome file'. This is exactly what it claims to be - it's the file that will be displayed when the application is successfully deployed and a user tries to access it. What we're saying here is that if a user accesses the root path of the web application (for example, http://:/ ) they will be presented with 'index.html'. This is a very basic way of providing an entry-point to your application, but is a great way of testing whether or not the application deployment has been successful.



  3.0 WebApp

  
    index.html
  


This is very, very basic stuff, but understanding how the deployment descriptor works is key to a bunch of more interesting stuff, including Servlets and the Spring MVC framework.

OpenShift and Doing Incredible Things


OpenShift is Amazing.

I've been working with Java for 7 years. I've never developed anything that wasn't either work or a university project, and I've certainly never developed anything that I published for the work to see. That has changed.

I didn't know how far hosting had come. I figured for a couple of dollars a month I could probably get access to a Unix server somewhere, where I could host a little Tomcat instance and throw a pre-compiled WAR file at it. What I didn't realise is that there are hosting solutions out there that are *deeply* integrated into my existing development environment.

So I write a pretty basic Java web app on my computer. I use Spring MVC to simplify the mechanics around my presentation tier. I use a Maven POM file to define my dependency on Spring's JARs. I version control this with git.

With OpenShift, it will create a new Git repository for me, and when I add my existing code to this repo, and push it to the OpenShift server, it will compile, build, package (including pulling in all my Maven dependencies) and deploy this for me. For free. With literally no effort on my part.

I actually feel a little cheated, there's a small amount of joy in doing these tasks yourself, but I can't argue that this is a huge step forward for the amateur Java developer. I really don't need to understand the details of any of the stack apart from the actual application development. No more messing around with build tools, no more server deployment issues.

Right now my first 'public' application - CarMatch - is simply a welcome page. But to update this to a fully-featured web-application would take me as long as it takes to push the Git-managed repository to the server, and however it takes to build and deploy.

Plenty of how-tos, guides and details on my plans for CarMatch are on their way, but this gushing first post seemed somewhat appropriate given the amount of freedom OpenShift has given me to publish my code with the minimum of overhead.