Friday, August 17, 2018

Spring MVC Java Configuration Example

In the post Spring MVC Example Using XML Configuration and Annotations we saw a Spring MVC example with XML configuration, here we’ll create the same MVC application using Spring MVC Java configuration.

In this Spring MVC example using Java configuration we’ll create two views (JSPs), that will give you a better idea about the controller mapping, how Java model bean is bound to a web form and the Spring web MVC flow ) (request - Servlet – Controller – Model – View).

Technologies used

Following is the list of tools used for the Spring web MVC example.

  1. Spring 5.0.8 Release (Spring core, spring web, spring webmvc).
  2. Java 10
  3. Tomcat server V 9.0.10
  4. Eclipse Photon 4.8.0 for Java EE development (This Eclipse version supports Java 10)

Creating project structure in Eclipse

In Eclipse select File – New – Dynamic Web Project.

Enter the project name, in this example name given is springmvc-config. You can also select the target runtime here itself as Apache Tomcat.

Spring MVC Java config project

Click next, in the web module page you don’t need to check the “Generate web.xml deployment descriptor” check box as web.xml is not needed you are going to configure servlet using java configuration. Click Finish.

Spring MVC Java config

Converting to Maven project

It’s convenient to use Maven for managing dependencies and building the application so we’ll use Maven in our Spring Web MVC example.

Right click on the created web project (springmvc-config). Select Configure – Convert to maven project.

In the window “Create new POM” give the name for artifact ID and Group ID. You can keep both as project name. Ensure that the packaging is war. For Name and description you can give “springmvc-config” and “spring mvc Java config example” respectively.

Spring MVC maven project

Adding Maven dependencies to pom.xml

Now you can add dependencies for Spring Web MVC project. Refer the pom.xml given below.

<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>springmvc-config</groupId>
  <artifactId>springmvc-config</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
  <name>springmvc-config</name>
  <description>spring mvc Java config example</description>
  <properties>
    <spring.version>5.0.8.RELEASE</spring.version>
  </properties>
    <dependencies>
    <dependency>
       <groupId>org.springframework</groupId>
       <artifactId>spring-core</artifactId>
       <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>4.0.0</version>
          <scope>provided</scope>
      </dependency>
    <!-- For JSTL tags -->
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
  </dependencies>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
        <configuration>
          <release>10</release>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>3.2.1</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

Spring MVC Java configuration

In spring MVC all requests go through DispatcherServlet which acts as a front controller. So first thing is to configure DispatcherServlet, since we are using Java config so it is not required to configure DispatcherServlet in web.xml. Here it will be defined using the Java class as follows.

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

public class SpringMVCConfigInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
  @Override
  protected Class<?>[] getRootConfigClasses() {
    // TODO Auto-generated method stub
    return null;
  }

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

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

Spring framework detects the class extending AbstractAnnotationConfigDispatcherServletInitializer, that class is automatically used to configure DispatcherServlet. Class defined in getServletConfigClasses() method is used to load Spring application context.

If there is any other application context that is loaded using the class defined in the method getRootConfigClasses(). In this example we are creating just the web application and there is no other application context so this method returns null.

GetServletMappings() method defines the URL pattern served by the DispatcherServlet.

As indicated in the above class WebConfig class is used for loading the application context.

WebConfig.java

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

@Configuration
@EnableWebMvc
@ComponentScan(basePackages="org.netjs.controller")
public class WebConfig implements WebMvcConfigurer {
 
 @Bean
 public ViewResolver viewResolver() {
  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
  resolver.setPrefix("/WEB-INF/jsp/");
  resolver.setSuffix(".jsp");
  return resolver;
 }
 /**
  * Configure a handler to delegate unhandled requests by forwarding to the
  * Servlet container's "default" servlet. A common use case for this is when
  * the {@link DispatcherServlet} is mapped to "/" thus overriding the
  * Servlet container's default handling of static resources.
  */
 public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
  configurer.enable();
 }
}

Here @Configuration indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions.

@EnableWebMvc annotation enables the annotation driven Spring MVC configuration.

@ComponentScan annotation enables the automatic discovery of beans in the given base package.

For resolving views InternalResourceViewResolver is used where two properties suffix and prefix are given. By this approach you don’t need to hard code the views but the views are resolved at run time using the configuration. For example if logical view name returned from controller is “home” then the JSP that has to be used as view will be found at the location- /WEB-INF/jsp/home.jsp

Spring Web MVC example classes

  1. Landing page (home page) where a message is displayed and there are two text boxes too to enter first name and second name and a submit button. The entered first name and last name are bound to a model bean.
  2. When the submit button is clicked, controller method which handles request for that click action is invoked and another view page (JSP) is called which displays the entered first name and last name in the first page.

Controller class

package org.netjs.controller;

import org.netjs.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class MessageController {
 @RequestMapping(value = "/", method = RequestMethod.GET)
 public String showHome(Model model) {
  model.addAttribute(new User());
  model.addAttribute("message", "This is my first MVC page");
  return "home";
 }
 
 @RequestMapping(value = "/showUser", method = RequestMethod.POST)
 public String showUser(@ModelAttribute("user") User user, Model model) {
  model.addAttribute("firstName", user.getFirstName());
  model.addAttribute("lastName", user.getLastName());
  return "user";
 }
}

As you can see the class is annotated with @Controller annotation which indicates it is a controller class and should be registered by the <context:component-scan> tag. Also there are two methods, first method showHome handles the request where path is “/”. Second controller method serves the request where path is "/showUser".

Model bean

public class User {
 private String firstName;
 private String lastName;
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
}

Spring Web MVC view pages

As you can see from controller methods, logical view names that are returned are “home” and “user” which means there should be two JSPs home.jsp and user.jsp inside folder /WEB-INF/jsp.

home.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Spring MVC tutorial - Home JSP</title>
</head>
<body>
  <h1>Hello World!</h1>
  <h4>Message- </h4><span>${message}</span>
  <form:form action="showUser" modelAttribute="user" method="post">
    <tr>
      <td>
        <form:label path="firstName">First Name</form:label>
      </td>
      <td>
        <form:input path="firstName" id="firstname" />
      </td>
    </tr>
    <tr>
      <td>
        <form:label path="lastName">Last Name</form:label>
      </td>
      <td>
        <form:input path="lastName" id="lastname" />
      </td>
    </tr>
    <input type="submit" value="Submit">
  </form:form>
</body>
</html>

In the controller method showHome() a message is set as attribute, which is displayed in this JSP. Method also sets an instance of User which is used to bind the properties of the bean to input values. Attribute path is used to set the values of the correct fields.

user.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Spring MVC tutorial - User</title>
</head>
<body>
  <h4>First Name</h4><span>${firstName}</span>
  <h4>Last Name</h4><span>${lastName}</span>
</body>
</html>

In this JSP, attributes set in the model, using the instance of the user is used to display those field values.

Building war for the Spring MVC application

Now you can build the application and package it as a war. Right click on project, select Maven build, in the opened window enter Goals as clean install and run it.

If you get “Build Success” on your console that means war is successfully built, otherwise check the error.

Running Spring Web MVC application using Tomcat

You can add Tomcat server to Eclipse IDE and run it from there itself, it is more convenient.

Right clicking on the server and selecting “Add and Remove” you should see your web application on the left hand side. You can select it and move it to right side so that it is configured to run on TomCat Server.

Start the server, your configured application will also be deployed to the server. Once the Tomcat server is successfully started you can run your Spring Web MVC application.

Aug 17, 2018 11:04:16 AM org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry register
INFO: Mapped "{[/],methods=[GET]}" onto public java.lang.String org.netjs.controller.MessageController.showHome(org.springframework.ui.Model)
Aug 17, 2018 11:04:16 AM org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry register
INFO: Mapped "{[/showUser],methods=[POST]}" onto public java.lang.String org.netjs.controller.MessageController.showUser(org.netjs.model.User,org.springframework.ui.Model)
Aug 17, 2018 11:04:16 AM org.springframework.web.servlet.handler.AbstractUrlHandlerMapping registerHandler
INFO: Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
Aug 17, 2018 11:04:16 AM org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
INFO: Looking for @ControllerAdvice: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Fri Aug 17 11:04:14 IST 2018]; root of context hierarchy
Aug 17, 2018 11:04:17 AM org.springframework.web.servlet.FrameworkServlet initServletBean
INFO: FrameworkServlet 'dispatcher': initialization completed in 3361 ms
Aug 17, 2018 11:04:17 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Aug 17, 2018 11:04:17 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8009"]
Aug 17, 2018 11:04:17 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 12373 ms

From the log displayed on the console you can verify that the URL paths given in the Controller class methods are mapped. Also the framework servlet (DispatcherServlet) is initialized.

With Tomcat server started and the application deployed you can view the application pages. To go to the home page, enter this URL- http://localhost:8080/springmvc-config/ in the browser. Change the port and application name as per your configuration.

Enter first name and last name, click submit. That will take you to the second page (user.jsp) displaying the entered values using the bound Model bean.

That's all for this topic Spring MVC Java Configuration Example. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Spring Web MVC Tutorial
  2. Spring MVC - Binding List of Objects Example
  3. Spring MVC Example With @RequestParam Annotation
  4. Spring MVC Exception Handling Overview
  5. Spring Batch Processing With List of Objects in batchUpdate() Method

You may also like-

  1. Spring Transaction Attributes - Propagation And Isolation Level Settings
  2. Wiring Collections in Spring
  3. @Required Annotation in Spring Framework
  4. Insert\Update Using JDBCTemplate in Spring Framework
  5. Difference Between Encapsulation And Abstraction in Java
  6. JVM Run-Time Data Areas - Java Memory Allocation
  7. Print Odd-Even Numbers Using Threads And wait-notify - Java Program
  8. Introduction to Hadoop Framework

No comments:

Post a Comment