Spring MVC 4 : Configurations and Controllers

Spring MVC allows creation of web-applications in a convenient, straightforward and fast way. Typically in a spring web application we had a web.xml and we  defined the front-controller configuration and the url pattern it will be looking on. In the dispatcher-servlet.xml where we use to defined a view-resolver for identifying the real view , and location to search for beans via component-scanning etc. You may have another spring.xml file as well.

Starting with the Servlet 3.0 specification, we can do away with the WEB-INF/web.xml configuration file. This was introduce in spring-mvc 3 but Spring mvc 4 now provides a better support for java configuration using annotation. Here we wont be using any xml files, just pure java configuration.

Make a ‘Dynamic web Project’ in Eclipse. Make sure you use servlet api 3 or above.  Right click the project -> Configure – > Convert to Maven project.

Here is the pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>spring-mvc-4-demo</groupId>
<artifactId>spring-mvc-4-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<properties>
<springframework.version>4.2.2.RELEASE</springframework.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.3</version>
</dependency>
</dependencies>

<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>

notice here is the maven-war-plugin declaration. As we will be completely removing web.xml, we will need to configure this plugin in order to avoid maven failure to build war package. Lets create a WebAppInitializer.java


package com.mynotes.spring.mvc4.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

public class WebAppInitializer implements WebApplicationInitializer {

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}

private AnnotationConfigWebApplicationContext getContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.setConfigLocation("com.mynotes.spring.mvc4.config.WebAppConfig");
return context;
}

}

Notice that this is what we use to do in web.xml. Map the dispatcher-servlet and set the url mapping. Now lets create the WebAppConfig.java


package com.mynotes.spring.mvc4.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@ComponentScan(basePackages = "com.mynotes.spring.mvc4")
@EnableWebMvc
public class WebAppConfig {

@Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");

return resolver;
}

}

This is where we define our view resolver and other front-controller stuff that we use to do in dispatcher-servlet.xml. Lets create our controller


package com.mynotes.spring.mvc4.controllers;

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

@Controller
public class DemoController {

@RequestMapping(value = "/greeting")
public String greeting(Model model) {
System.out.println("greeting called");
model.addAttribute("greeting", "Greetings Everyone!!");

return "greetings";
}

}

This is same as previous versions of spring having a request mapping which is default to GET request. It returns a string which is the jsp that will be resolved by the view resolver. Currently our project structure something like this

springMvc1

index.jsp at WebContent root


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome page</title>
</head>
<body>
<h1>Welcome</h1>
</body>
</html>

greetings.jsp in view folder inside WEB-INF. Its recommended that we keep our view files inside WEB-INF so that its not publically available and is accessible through via our controllers only, unlike index.jsp which can be accessed directly.


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Hello</title>
</head>
<body>
<h1>${greeting}</h1>
</body>
</html>

Lets run on tomcat

springmvc4Demoresult1

springmvc4Demoresult2

This pure java configuration is just another option to configure our web application. You can still use web.xml, infact many people use a combination of both, by having a web.xml and pointing it to WebAppConfig class.

 

Advertisements
%d bloggers like this: