Spring MVC Full Java Based Configuration Example

This example will demo how to create a Spring MVC project without any XML configuration file also called web.xml-less. It will only use the java annotations to configure a Spring MVC project. This example also implements a login function. There is a login form page, and when the user inputs the correct username and password, it will show the login success page. If the input is wrong, it will display the error message above the login form.

1. Example Demo.

  1. The example page is almost the same as Spring MVC Login Example. But the backend implementation is different from it. It uses only java annotation to config all beans.

2. Create The Example Project.

  1. Click File —> New —> Spring Legacy Project menu item to open the New Spring Legacy Project window, then select Spring MVC Project template in the Spring Legacy Project wizard dialog. The project name is SpringMVCJavaBased.
  2. Click the Next button, input the top-level package name ( such as com.dev2qa.mvc ) in the next Project Settings – Spring MVC Project dialog.
  3. Click the Finish button to complete the wizard, and then you can see below wizard created files in the package explorer panel.
    sts-spring-mvc-project-template-create-files-list
  4. Because we will not use any XML file as spring configuration, so we should remove all unnecessary files such as servlet-context.xml, root-context.xml, web.xml, home.jsp.
  5. Now the project is clear and we will edit some files and add some files.
  6. Before continue, let us have a glance at the final example project files when the example is complete. Then we will introduce them one by one.
    C:\WORKSPACE\WORK\DEV2QA.COM-EXAMPLE-CODE\SPRINGBOOT\SPRINGMVCJAVABASED
    │   .classpath
    │   .project
    │   .springBeans
    │   pom.xml
    │
    ├───.settings
    │       org.eclipse.jdt.core.prefs
    │       org.eclipse.m2e.core.prefs
    │       org.eclipse.wst.common.component
    │       org.eclipse.wst.common.project.facet.core.xml
    │       org.eclipse.wst.validation.prefs
    │       org.springframework.ide.eclipse.beans.core.prefs
    │       org.springframework.ide.eclipse.core.prefs
    │
    ├───src
    │   ├───main
    │   │   ├───java
    │   │   │   └───com
    │   │   │       └───dev2qa
    │   │   │           └───mvc
    │   │   │               ├───beans
    │   │   │               │       UserAccountBean.java
    │   │   │               │
    │   │   │               ├───config
    │   │   │               │       CustomDispatcherConfig.java
    │   │   │               │       CustomDispatcherServlet.java
    │   │   │               │
    │   │   │               └───controller
    │   │   │                       LoginController.java
    │   │   │
    │   │   ├───resources
    │   │   │   └───config
    │   │   │           messages_en_US.properties
    │   │   │
    │   │   └───webapp
    │   │       └───pages
    │   │               login_success.jsp
    │   │               show_login.jsp
    │   │
    │   └───test
    │       └───resources
    │               log4j.xml

3. Edit pom.xml

  1. The first thing we need to do is to edit pom.xml to the below content.
    <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>org.springframework.samples.service.service</groupId>
        <artifactId>SpringMVCJavaBased</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <!-- Spring framework used constants variable  -->
        <properties>
            <spring.version>5.0.0.BUILD-SNAPSHOT</spring.version>
            <servlet.api.version>3.1.0</servlet.api.version>
        </properties>
    
    
        <repositories>
            <!-- This repository is where the spring framework dependencies jar file download. -->
            <repository>
                <id>spring-snapshots</id>
                <name>Spring Snapshots</name>
                <url>https://repo.spring.io/libs-snapshot</url>
                <snapshots>
                    <enabled>true</enabled>
                </snapshots>
            </repository>
        </repositories>
    
        <dependencies>
            <!-- Below are the basic spring container dependencies library. -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <!-- Below dependency is used for spring mvc framework. -->
            <!-- 
            <dependency>
                 <groupId>org.springframework</groupId>
                 <artifactId>spring-web</artifactId>
                 <version>${spring.version}</version>
              </dependency>
              -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
    
            <!-- Below dependency is used for servlet and jsp. -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>${servlet.api.version}</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>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>
    
        </dependencies>
    
        <build>
            <finalName>spring-mvc-example</finalName>
            <plugins>
                <!-- Because this project do not use web.xml so need below settings. -->
                <plugin>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.3</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
    
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>2.2</version>
                    <configuration>
                        <username>tomcat</username>
                        <password>tomcat</password>
                        <!-- update true will override the existing deployed war file in tomcat -->
                        <update>true</update>
                    </configuration>
                </plugin>
    
            </plugins>
        </build>
    
    </project>

4. Create Java Class To Make Spring Bean Configuration.

  1. Instead of using XML, we create a java class to make a bean configuration. The java class must extends org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter.
  2. And it should be annotated with @Configuration, this annotation means this bean is a configuration bean.
  3. CustomDispatcherConfig.java
    package com.dev2qa.mvc.config;
    
    import org.springframework.context.MessageSource;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.support.ReloadableResourceBundleMessageSource;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    import org.springframework.web.servlet.view.InternalResourceViewResolver;
    import com.dev2qa.mvc.beans.UserAccountBean;
    
    @EnableWebMvc
    @Configuration
    @ComponentScan(basePackages="com.dev2qa.mvc")
    public class CustomDispatcherConfig extends WebMvcConfigurerAdapter {
    
        public static final String ENCODING_UTF = "UTF";
    
        public static final String ENCODING_UTF_8 = "UTF-8";
    
        public static final long MAX_UPLOAD_FILE_SIZE = 52428807;
    
        public static final long MAX_UPLOAD_PER_FILE_SIZE = 5242880;
    
        /* This configuration will use InternalResourceViewResolver to resolve jsp pages back to client user.
         * All the pages will be located in src/main/webapp/pages.
         *  */
        @Bean
        public InternalResourceViewResolver getJspViewResolver() {
    
            InternalResourceViewResolver ret = new InternalResourceViewResolver();
    
            ret.setPrefix("/pages/");
    
            ret.setSuffix(".jsp");
    
            ret.setOrder(1);
    
            return ret;
    
        }
    
    
        /* messageSource method name can not be change to others, else there will has errors when browse web page.
         * messageSource is used to make page text internalization. The message file is saved in src/main/resources/config/messages_en_US.preoperties
         * You should create config folder by yourself if it dose not exist.
         * */
        @Bean(name = "messageSource")
        public MessageSource getMessageSource() {
            ReloadableResourceBundleMessageSource ret = new ReloadableResourceBundleMessageSource();
    
            ret.setBasename("classpath:config/messages_en_US");
    
            ret.setCacheSeconds(1);
    
            ret.setUseCodeAsDefaultMessage(true);
    
            ret.setDefaultEncoding(ENCODING_UTF);
    
            return ret;
        }
    
        /* Register the UserAccountbean. */
        @Bean(name = "userAccountBean")
        public UserAccountBean getUserAccountBean() {
            UserAccountBean ret = new UserAccountBean();
            return ret;
        }
    
    }

5. Create Java Class To Add Dispatcher Servlet To Spring Web Application Context Dynamically.

  1. This class must implement org.springframework.web.WebApplicationInitializer interface. It also needs to be annotated by @Configuration.
  2. CustomDispatcherServlet.java
    package com.dev2qa.mvc.config;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRegistration;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.WebApplicationInitializer;
    import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
    import org.springframework.web.servlet.DispatcherServlet;
    
    @Configuration
    public class CustomDispatcherServlet implements WebApplicationInitializer {
    
        @Override
        public void onStartup(ServletContext servletContext) throws ServletException {
    
            AnnotationConfigWebApplicationContext dispatcherServletContext = new AnnotationConfigWebApplicationContext();
    
            dispatcherServletContext.register(CustomDispatcherConfig.class);
    
            DispatcherServlet dispatcherServlet = new DispatcherServlet(dispatcherServletContext);
    
            // Create a servlet dynamically.
            ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", dispatcherServlet);
    
            dispatcher.setLoadOnStartup(1);
    
            // Add servlet mapping url. All url end with .html will be processed by this servlet.
            dispatcher.addMapping("*.html");
        }
    
    }

6. Controller Class.

  1. LoginController.java
    package com.dev2qa.mvc.controller;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.beans.factory.annotation.Autowired;
    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.context.WebApplicationContext;
    
    import com.dev2qa.mvc.beans.UserAccountBean;
    
    @Controller
    public class LoginController {
    
        /* Autowired the web application context object. */
        @Autowired
        private WebApplicationContext webContext;
    
        public static final String STATUS_MESSAGE = "STATUS_MESSAGE";
    
        // This method map to http://localhost:8080/SpringMVCXmlBased/showLogin.html
        @RequestMapping("/showLogin.html")
        public String showLoginPage() {
            return "show_login";
        }
    
        // This method map to http://localhost:8080/SpringMVCXmlBased/doLogin.html
        @RequestMapping("/doLogin.html")
        public String doLogin(Model model, @ModelAttribute("userName")
                String userName,
                              @ModelAttribute("password")
                                      String password,
                              HttpServletRequest req) {
    
            System.out.println("userName = " + userName);
    
            System.out.println("password = " + password);
    
            // Get spring bean from the autowired web application context.
            UserAccountBean userAccountBean = (UserAccountBean)webContext.getBean("userAccountBean");
    
            boolean checkResult = userAccountBean.checkUserLogin(userName, password);
    
            if(checkResult)
            {
                model.addAttribute(STATUS_MESSAGE, "User account is correct. ");
                return "login_success";
            }else
            {
                model.addAttribute(STATUS_MESSAGE, "User account is not correct. ");
                return "show_login";
            }
        }
    }

7. Business Logic Java Bean.

  1. UserAccountBean.java
    package com.dev2qa.mvc.beans;
    
    public class UserAccountBean {
    
        public boolean checkUserLogin(String userName, String password)
        {
            boolean ret = false;
    
            if("Jerry".equalsIgnoreCase(userName) && "888888".equals(password))
            {
                ret = true;
            }
            return ret;
        }
    
    }

8. Login Form JSP.

  1. show_login.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
        <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title><spring:message code="login_form_title"/></title>
    </head>
    <body>
    
        <div style="margin:10px">
            <h2>${STATUS_MESSAGE}</h2>
            <form action="${pageContext.request.contextPath}/doLogin.html" method="post">
    
                User Name : <input type="text" id="userName" name="userName"/><br/>
    
                Password : <input type="password" id="password" name="password"/><br/>
    
                <input type="submit" value="Login" />
    
            </form>
        </div>
    
    </body>
    </html>

9. Login Success JSP.

  1. login_success.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
        <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title><spring:message code="login_success_title"/></title>
    </head>
    <body>
        <h2>${STATUS_MESSAGE}</h2>
    </body>
    </html>

10. Message Definition Properties File.

  1. src/main/resources/config/messages_en_US.properties
    #Title Labels
    login_form_title=Login Form Page
    login_success_title=Login Success Page

Reference

  1. How To Deploy A Maven Project To Tomcat From Eclipse
  2. Tomcat Remote Debugging Eclipse
  3. Spring MVC Login Example

1 thought on “Spring MVC Full Java Based Configuration Example”

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.