Spring MVC login example
In this example, we shall create a simple Login Application using Spring MVC framework.
Spring Framework follows the MVC design by default so that the view,controller and Data modules are loosely coupled. In a typical Spring MVC Application, the role played are :
- View : JSP
- Controller : Classes annotated with
@Controller
- Data : Repository Classes
With this knowledge we can start building our MVC application. We will explain each component as we introduce them in the example.
Here’s the project structure :
Let’s begin with the login.jsp :
Login.jsp
<%@include file="include.jsp"%> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!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=ISO-8859-1"> <title>Login</title> </head> <body> <form:form id="loginForm" method="post" action="login" modelAttribute="loginBean"> <form:label path="username">Enter your user-name</form:label> <form:input id="username" name="username" path="username" /><br> <form:label path="username">Please enter your password</form:label> <form:password id="password" name="password" path="password" /><br> <input type="submit" value="Submit" /> </form:form> </body> </html>
We have imported the Spring tab libraries in the include.jsp
. Using the spring tags, we can bind the Form with the spring view bean using the commandname
or modelattribute
attribute of the form tag. The action attribute submits to the Controller
.
include.jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
Once the user enters the details and clicks the submit button the control is transferred to the deployment descriptor, web.xml
.
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>SpringMVCloginExample</display-name> <servlet> <servlet-name>springLoginApplication</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath://resource//springWeb.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springLoginApplication</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
In the web.xml
, we configure the DispatcherServlet
to serve the requests via the Spring Container. The spring web container, reads the springWeb.xml
to initiate the Controllers by scanning the packages for the annotations.
springWeb.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.jcg" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/jsp/" /> <property name="suffix" value=".jsp" /> </bean> <import resource="springBeanConfiguration.xml"/> </beans>
The LoginController
is configured to serve the requests for the URL : contextpath
/login. However, the two methods serve different type of requests depending on the type of methods using the method
parameter and the RequestMethod
enum. When the user hits the login URL for the first time, it is a GET request and hence is handled by the displayLogin
method which displays the login.jsp page to the user.
LoginController.java
package com.jcg.examples.controller; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; import com.jcg.examples.delegate.LoginDelegate; import com.jcg.examples.viewBean.LoginBean; @Controller public class LoginController { @Autowired private LoginDelegate loginDelegate; @RequestMapping(value="/login",method=RequestMethod.GET) public ModelAndView displayLogin(HttpServletRequest request, HttpServletResponse response) { ModelAndView model = new ModelAndView("login"); LoginBean loginBean = new LoginBean(); model.addObject("loginBean", loginBean); return model; } @RequestMapping(value="/login",method=RequestMethod.POST) public ModelAndView executeLogin(HttpServletRequest request, HttpServletResponse response, @ModelAttribute("loginBean")LoginBean loginBean) { ModelAndView model= null; try { boolean isValidUser = loginDelegate.isValidUser(loginBean.getUsername(), loginBean.getPassword()); if(isValidUser) { System.out.println("User Login Successful"); request.setAttribute("loggedInUser", loginBean.getUsername()); model = new ModelAndView("welcome"); } else { model = new ModelAndView("login"); model.addObject("loginBean", loginBean); request.setAttribute("message", "Invalid credentials!!"); } } catch(Exception e) { e.printStackTrace(); } return model; } }
When the user submits the form the web-method is the Post method. So, the method invoked is executeLogin
.
The LoginController
uses the LoginDelegate
to delegate the business logic into the delegate. The LoginDelegate
is autowired
into the controller.
LoginDelegate.java
package com.jcg.examples.delegate; import java.sql.SQLException; import com.jcg.examples.service.UserService; public class LoginDelegate { private UserService userService; public UserService getUserService() { return this.userService; } public void setUserService(UserService userService) { this.userService = userService; } public boolean isValidUser(String username, String password) throws SQLException { return userService.isValidUser(username, password); } }
The LoginDelegate bean is configured in the springBeanConfiguration.xml
. Spring container loads this xml when the springWeb.xml
is loaded. The beans are defined in a separate XML to maintain code segregation. All bean definitions are written in this file.
springBeanConfiguration.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="loginDelegate" class="com.jcg.examples.delegate.LoginDelegate"> <property name="userService" ref="userService"></property> </bean> <bean id="userService" class="com.jcg.examples.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property> </bean> <bean name="userDao" class="com.jcg.examples.dao.impl.UserDaoImpl"> <property name="dataSource" ref="dataSource"></property> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/jcg" /> <property name="username" value="root" /> <property name="password" value="toor" /> </bean> </beans>
The Logindelegate
uses the UserService
Interface for the service layer. As we all know, we should code to the interface instead of the implementation for the loosely coupled code. However, the injection that we make is of the concrete implementation which can be changed by just making changes in the Xml where the bean is defined. This is one of the benefits of spring’s IoC.
UserService.java
package com.jcg.examples.service; import java.sql.SQLException; /** * @author CENTAUR * */ public interface UserService { public boolean isValidUser(String username, String password) throws SQLException; }
Here’s, the UserService
implementation we will be using for this project.
UserServiceImpl.java
package com.jcg.examples.service.impl; import java.sql.SQLException; import com.jcg.examples.dao.UserDao; import com.jcg.examples.service.UserService; public class UserServiceImpl implements UserService { private UserDao userDao; public UserDao getUserDao() { return this.userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public boolean isValidUser(String username, String password) throws SQLException { return userDao.isValidUser(username, password); } }
The service layers delegates the actual verification and database call to the DAO layer. We inject the Datasource
into the UserDao
implementation. The datasource is defined in the xml from where it is injected into the DAO. We can also configure to use Hibernate and JPA as shown in this previous article.
UserDao.java
package com.jcg.examples.dao; import java.sql.SQLException; /** * @author CENTAUR * This interface will be used to communicate with the * Database */ public interface UserDao { public boolean isValidUser(String username, String password) throws SQLException; }
UserDaoImpl.java
package com.jcg.examples.dao.impl; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import com.jcg.examples.dao.UserDao; /** * @author CENTAUR * */ public class UserDaoImpl implements UserDao { DataSource dataSource ; public DataSource getDataSource() { return this.dataSource; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } @Override public boolean isValidUser(String username, String password) throws SQLException { String query = "Select count(1) from user where username = ? and password = ?"; PreparedStatement pstmt = dataSource.getConnection().prepareStatement(query); pstmt.setString(1, username); pstmt.setString(2, password); ResultSet resultSet = pstmt.executeQuery(); if(resultSet.next()) return (resultSet.getInt(1) > 0); else return false; } }
The Dao sends appropriate response back to the controller. The Controller accordingly redirects the user to the appropriate page. The controller returns the ModelandView
object with the name of the view. The InternalViewResolver
defines the exact view to be rendered by appending the prefix and suffix.
In this example, for the sake of brevity we are using jsp. Spring supports multiple types of views like Apache tiles, Apache Velocity,XLS, CSV etc.. and they can even be configured on priority.
Here’s the welcome.jsp
which shows the logged in username with a welcome message.
welcome.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!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=ISO-8859-1"> <title>Welcome</title> </head> <body> <center>Welcome ${loggedInUser}</center> </body> </html>
If the login fails, the user is shown the same login.jsp with the Invalid Credentials.
Output:
On Successful login :
On Failure :
Download the Source Code :
In this example, we understood the Model, View and Controller architecture using Spring MVC. Also, we saw how the IoC helps in keeping the code loosely coupled.
You can download the source code of this example here: SpringMVCloginExample.zip
LoginBean code its not there
Login application in spring ———————————————————————————————— pom,xml file are 1.8 4.3.0.RELEASE 5.1.36 2.9.0 junit junit 3.8.1 test org.springframework spring-context ${spring.version} org.springframework spring-webmvc ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-orm ${spring.version} javax.servlet javax.servlet-api 3.1.0 provided javax.servlet.jsp javax.servlet.jsp-api 2.3.1 provided javax.servlet jstl 1.2 mysql mysql-connector-java ${mysqlconnector.version} Configuration file —————————————————————————- WebMvcConfig.java package com.krunal.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @EnableWebMvc @ComponentScan(basePackages=”com.krunal”) @PropertySource(value= {“classpath:application.properties”}) public class WebMvcConfig extends WebMvcConfigurerAdapter { @Autowired Environment env; @Bean public ViewResolver getViewResolver() { InternalResourceViewResolver view= new InternalResourceViewResolver(); view.setPrefix(“/views/”); view.setSuffix(“.jsp”); return view; }… Read more »
Hey guy..I cannot running project, while im testing the UserDaoImpl, this issue NullPointerExeption trigger with line code have contains dataSource.getCOnnectio().
How to fix that ?
Login application in spring ———————————————————————————————— pom,xml file are 1.8 4.3.0.RELEASE 5.1.36 2.9.0 junit junit 3.8.1 test org.springframework spring-context ${spring.version} org.springframework spring-webmvc ${spring.version} org.springframework spring-web ${spring.version} org.springframework spring-orm ${spring.version} javax.servlet javax.servlet-api 3.1.0 provided javax.servlet.jsp javax.servlet.jsp-api 2.3.1 provided javax.servlet jstl 1.2 mysql mysql-connector-java ${mysqlconnector.version} Configuration file —————————————————————————- WebMvcConfig.java package com.krunal.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver; @Configuration @EnableWebMvc @ComponentScan(basePackages=”com.krunal”) @PropertySource(value= {“classpath:application.properties”}) public class WebMvcConfig extends WebMvcConfigurerAdapter { @Autowired Environment env; @Bean public ViewResolver getViewResolver() { InternalResourceViewResolver view= new InternalResourceViewResolver(); view.setPrefix(“/views/”); view.setSuffix(“.jsp”); return view; }… Read more »
i have error– http status 404 not found
I am getting resource not found error, status 404
bean class is missing