Alex Collins is a enterprise Java developer and currently works in the UK. He has worked in the insurance, publishing, telecoms and supply chain. In his spare time he codes in Python, Clojure and Scala (but not at the same time) and enjoys a multitude of sports. His catchphrase is K.I.S.S! Alex has posted 20 posts at DZone. You can read more from them at their website. View Full User Profile

Modern-day web development with Maven, Mercurial and Spring MVC

07.19.2010
| 8291 views |
  • submit to reddit

Within minutes you can be up-and-running with version control, build/packaging and a non-intrusive web framework. Here's how!

Open source gives the modern developer so many choices, from the operating system you code on, to the IDE and even down to the container your WARs/EARs are deployed on. Put simply: it's never been better to be a developer than now.

This short tutorial gives a quick "getting started" guide to three excellent technologies you should be familiar with - Maven, Mercurial and Spring MVC.

Setting the scene

Let's create a project using maven and particularly its webapp archetype:

mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-webapp 
-DarchetypeArtifactId=maven-archetype-webapp
Getting it versioned

Most distributed version control systems (DVCS) allow you to get your code into a repository in seconds, which is a big win for developers because laziness is rife! Let's change into our newly created project's directory and then initialise, add and then commit to a new Mercurial repository.

$ hg init .
$ hg add .
adding pom.xml
adding src/main/webapp/WEB-INF/web.xml
adding src/main/webapp/index.jsp
$ hg com -m "initial commit"

Now you're safe - any changes you've made can be committed and any mistakes can be reverted. Let's see what Mercurial ("hg") can do for us. What's the status of our repository right now?

$ hg st

OK, no news is good news. Let's add Spring MVC integration to our web.xml in src/main/weapp/WEB-INF/.

<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>

Now we've modified our file, let's get it into our repository using hg again

$ hg st
M src/main/webapp/WEB-INF/web.xml

Mercurial's telling us that there's one modified file. Before we commit, let's make sure we've done all that's necessary to get Spring MVC up and running with our project by adding the dispatcher-servlet.xml file (which is our Spring context descriptor). Create the file 'dispatcher-servlet.xml' under src/main/webapp/WEB-INF/ and in it place the following:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

<context:component-scan base-package="com.mycompany.app"/>

<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>

Great, now we've got Spring integrated with our web application. As that's one changeset let's commit it to Mercurial so that it's all set in stone before we start writing our basic controller. You'll notice that if you run "hg st" (status) you'll have src/main/webapp/WEB-INF/dispatcher-servlet.xml marked with a ?. This means that Mercurial sees a file that is not in version control. Just run "hg add src/main/webapp/WEB-INF/dispatcher-servlet.xml" to add it to the repository. Running "hg st" after that will show it with a "A" before it - this is stating that it's ready to be added whenever you commit.

$ hg add src/main/webapp/WEB-INF/dispatcher-servlet.xml
$ hg st
M src/main/webapp/WEB-INF/web.xml
A src/main/webapp/WEB-INF/dispatcher-servlet.xml
$ hg com -m "Integrate Spring MVC"

Done! Easy as that. Now all we need is to make sure we've got Spring MVC and Spring Core added to our dependencies in our pom.xml and then we can start coding

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>2.5.1</version>
</dependency>

Now without prompting, commit that to your repository ;)

The only aspect left to do is to actually do some programming. In 2.5 Spring released annotations for controllers that allow you to get away from the majority of XML configuration you would otherwise need. I personally think this is a big plus; if you're used to working in a large team with a lot of change going on you'll know that Spring XML configuration files just add to the bloat and complexity of a merge.

The first annotation you'll come across is @Controller which marks it as a controller (duh!) for Spring to manage. This annotaion is class-level and should be applied to any class you want Spring to expose. Just think - you've already gotten rid of 8 lines of servlet declaration and mapping in your web.xml!

Next you'll use @RequestMapping. This is a method-level annotation and tells Spring what URL mapping should be used for requests. We previously configured all .html content to go via the Dispatcher servlet so remember that when configuring URLs this way. Let's start. Below is a snippet of code that you should add to src/main/java/com/mycompany/app/view/IndexController.java (remember to create that directory as our webapp archetype doesn't require it!).

package com.mycompany.app;

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

@Controller
public class IndexController {

@RequestMapping("/index.html")
public String indexHandler() {
return "index";
}

}

The above class is very simple but a great example of how annotations can be used with Spring to get something up-and-running very quickly. From top to bottom it's obvious what's going on - apart from the return "index"; which if you know Spring MVC should be self-explanatory as it's just the JSP URI that's build up using the prefix and suffix characters in the Web XML- and to know that it's not tied to a framework is also a plus. You're not extending or implementing something from yet another 3rd-party codebase, and you're free to structure it as your organisation pleases (or indeed dictates!).

Oh, remember to "hg commit" your changes! Next time we'll extend the application to use the @RequestParam annotation and more!

Conclusion

So, now you have a version-controlled web application using Spring MVC, Mercurial and Maven. There's very little to it!

Published at DZone with permission of its author, Alex Collins.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Cloves Almeida replied on Mon, 2010/07/19 - 7:48pm

The beauty of open-source. My stack is Gradle, Bazaar and Seam. And it's just as easy.

Alex Collins replied on Tue, 2010/07/20 - 1:56am in response to: Cloves Almeida

Aye, so much choice and such quality!

Joel Realubit replied on Sat, 2010/08/07 - 4:16pm

Nice articles (this, and the next in the series)! Got a good start with Mercurial from this -- thanks!

With minor tweaks though, the example can be updated to Spring 3.0. The dispatcher-servlet.xml file just needs the versions of the xsd's changed from '2.5' to '3.0', and the pom.xml file just needs to have the ff dependencies instead:

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.0.0.RELEASE</version>
</dependency>
</dependencies>

The actual Java code, though, can remain the same.

Again, thanks for the informative articles! :)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.