Spring MVC Sample Application Using Java Config

With recent advances in Spring framework (Spring 3.1), developers now have an option to configure Spring with Java classes rather than using XML files. This also includes configuring the DispatcherServlet in Java classes rather than in web.xml.


Configuring DispatcherServlet with Java Config

In a Servlet 3.0 environment, the container looks for any classes that implements javax.servlet.ServletContainerInitializer interface. If any such class is found, it is used to configure the Servlet container.

Spring provides an implementation of that interface called SpringServletContainerInitializer which, in turn, looks for classes that implement WebApplicationInitializer for getting configuration information.

The class below can be used to configure Servlet container:

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }
}

Notice that the class above extends AbstractAnnotationConfigDispatcherServletInitializer, it is an implementation of WebApplicationInitializerHence this class can be used to configure Servlet container.

Recall that a Spring web application has two application context:

  • Root Application Context initialized by ContextLoaderListener
  • Web Application Context initialized by DispatcherServlet

The getRootConfigClasses() method should return an array of all classes that configures the Root Application Context. Similarly, the getServletConfigClasses() method should return an array of all classes that configures the Web Application Context.

In our case RootConfig configures the Root Application Context and WebConfig configures the DispatcherServlet.

The getServletMappings() method is used to identify one or more paths the DispatcherServlet is mapped to.

Note: It is important to note that Java Config will work only if the application is deployed to a server that supports Servlet 3.0.

WebConfig

The WebConfig class is shown below. It is used to configure DispatcherServlet and define all beans that will be contained in the Web Application Context.

@Configurable
@EnableWebMvc
@ComponentScan(basePackages="cubearticle")
public class WebConfig extends WebMvcConfigurerAdapter{
    
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver =
        new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/pages/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
    
    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

It is annotated with @Configuration to let Spring understand that the class should be used for configuring beans.

@EnableWebMvc is equivalent to <mvc:annotation-diven /> in XML config. It is used to enable Spring MVC features by creating certain beans that would be used internally by Spring.

@ComponentScan indicates that Spring should scan packages for  discovering and wiring beans.

Next we need a View Resolver. Thus we defined an InternalResourceViewResolver. It applies the prefix and suffix to the logical view name to decide the actual view. For example if the logical view name is 'homePage', the actual view will be resolved as '/WEB-INF/pages/homePage.jsp'.

Finally notice that WebConfig class extends WebMvcConfigurerAdapter. We override the configureDefaultServletHandling() method of WebMvcConfigurerAdapter and call the enable() method of DefaultServletHandlerConfigurer.  By doing this we are asking DispatcherServlet to forward all requests for static resources to Servlet Container's default handler.

Shown below is our RootConfig class. Its is left blank since our sample application doesn't requires any beans to be declared for the root config. However any typical application would require to define beans in it.

public class RootConfig { }

The Welcome Page: homePage.jsp

Shown below is the welcome page of our application. It shows a simple message and displays a form which asks the user for his name and a small message.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Welcome</title>
</head>
<body>
    Welcome to Spring MVC
    <br>
    <form action="hello" method="post">
	<label>Enter your name: </label><input type="text" name="user"><br>
	<label>Enter a short message: </label><input type="text" name="message"><br>
	<input type="submit" value="Submit">
    </form>
</body>
</html>

Controller

Shown below is our controller which will serve the request when the user enter's his name and a message.

@Controller
public class MyController {
    @RequestMapping(value="hello", method=RequestMethod.POST)
    public String sayHello(@RequestParam String user, @RequestParam String message, Model model){
        model.addAttribute("user", user);
        model.addAttribute("message",message);
        return "hello";
    }
}

The class is annotated with @Controller, which tells Spring to consider this class as a Spring Controller and create a bean for it. It is a specialized form of @Component.

The value attribute of @RequestMapping annotation specifies the request path this method will handle. The method attribute defines the HTTP method this method can handle.

The sayHello() method accepts 3 parameters. The parameters user and message are annotated with @RequestParam annotation. This is used to wrap the request paramaters in the method parameters. The user and message parameters passed from the form in the welcome page are captured in this method. A Model object is also passed as a parameter which is used to encapsulate the model data and send it over to the view. We add the form paramaters (user & message) in the model object, so that they can be extracted in the view.

Finally, the method returns a logical view name 'hello', which is resolved by the InternalViewResolver as /WEB-INF/pages/hello.jsp.


View: hello.jsp

Our view, hello.jsp is shown below which prints the user's name and the short message.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <title>Hello World</title>
</head>
<body>
    <c:out value="${user}" /> says 
    <c:out value="${message}" />
</body>
</html>

The first line is a taglib declaration which imports the JSTL tag library. We would use JSTL to retrieve the name and the message from the model. Notice the use of EL (expression language) to extract the name and message value from the model object set in the controller.


Output

The image below shows the output of our Spring MVC Sample Application.

SQL MVC Output

Download Source Code

You can download the source code of the Sample Spring MVC Application discussed in this article.

POPULAR ARTICLES

Creating Conditional Beans in Spring

The concept of condition beans enables Spring to restrict the creation of any bean depending on the evaluation of a condition. These beans get created only when a preset condition is evaluated as true

View Article

Accepting Request Param and Path Variable in Spring Controller

Spring MVC provides various ways through which a client browser can pass data to the Controller. In this article we will discuss about accepting Request Parameters and Path Variables in Spring Contr..

View Article

Generate Namespace & Schema Information using JAXB

Most xml documents used in enterprise applications makes use of namespace to avoid element name conflicts. This article talks about generating these namespace and schema information when marshaling...

View Article

Switching Database Profile using Spring Profiles

We are most likely to have separate db configuration for different environment like development and production environment. Spring profiles provide a convenient way to switch db profiles at runtime.

View Article

SQL and its Sub-Languages

SQL (Structured Query Language) is a language understood by most modern databases. It is an ANSI (American National Standard Institute) standard language which is used to manipulate databases.

View Article

Introducing JUnit Rule

Junit Rules allows developers to add additional functionalities that can applied to all test methods in a test class. It is similar to the concept of custom test runners but with reduced restrictions.

View Article

Addressing Ambiguity in Spring Autowiring

Spring autowiring is powerful concept, but we should be very cautious while using it. We may end up in creating ambiguity while autowiring beans, which will cause autowiring to fail.

View Article

Creating and Using Synonym in Oracle Database

Synonyms are database objects used to provide duplicate names to existing objects in the database. It is just an alternate name used to hide the original name of the object.

View Article

Creating and Using Sequence in Oracle Database

A sequence is used to auto-generate numbers in ascending or descending order which can serve as a primary key or a part of it (in case of composite key).

View Article

Creating and Manipulating Constraints in Oracle Database

Constraints are used to impose certain rules on columns to avoid invalid data entry into the table. If any of the constraint is violated the operation fails.

View Article

Integrating Log4J with Perf4J for Performance Logging

Perf4j is an open source logging framework used primarily for monitoring performance statistics in java applications. Log4j has the ability to integrate with perf4j to capture performance data.

View Article

Tagging in GIT

Tagging allows us to mark a specific point in the commit history or snapshot. A tag is typically used to mark a project release. This article shows how to create tags in Git.

View Article