Overview
In this tutorial, we show you how to create Web Application with Spring 4 MVC, Spring Security User Registration, Spring MVC Login Form and Logout Example using Eclipse IDE, Mysql DatabaseFollow the steps mentioned below to develop this application.
Video Tutorials
Create Database
CREATE DATABASE `jack_rutorial_demo`;
Create Database Table
Creating `users` TableCREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(45) NOT NULL DEFAULT '', `password` varchar(200) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;Creating `user_roles` Table
CREATE TABLE `user_roles` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(45) NOT NULL DEFAULT '', `role` varchar(45) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Creating `persistent_logins` Table
CREATE TABLE `persistent_logins` ( `username` varchar(64) NOT NULL, `series` varchar(64) NOT NULL, `token` varchar(64) NOT NULL, `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`series`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Creating a default admin user
The following code creates a users named “admin” with password is '123', defines an “ROLE_ADMIN” role.INSERT INTO USERS(USERNAME,PASSWORD) VALUES('admin','$2a$10$Ii8O.wtxIeYQuXcbhcQ/WOngxwb1KrnAVOOLi6SaW8KfPWq7O6tsa');
INSERT INTO USER_ROLES(USERNAME,ROLE) VALUES('admin','ROLE_ADMIN');
Project Structure
Create Maven Project
- Launch Eclipse IDE.
- Go to File-> New-> Others... Select Maven Project under Maven category then click Next.
- In New Maven Project wizard, select "Create a simpel project(skip archetype selection)" and click on Next
- In next wizard, type "com.jackrutorial" in the "Group ID:" field
- Type "SpringMVCSignupLoginPasswordEncoder" in the "Artifact Id:" field
- Packaging -> War
- Click Finish.
Update pom.xml to include required dependencies
Open pom.xml file and add the following dependencies in it.<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>com.jackrutorial</groupId>
<artifactId>SpringMVCSignupLoginPasswordEncoder</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</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>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Configure WebApp and Spring Security
- Right click to the src folder, select New -> Package
- Enter "com.jackrutorial.config" in Name: field
- Click Finish
package com.jackrutorial.config;
import javax.sql.DataSource;
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.support.ResourceBundleMessageSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = { "com.jackrutorial" })
public class WebConfig extends WebMvcConfigurerAdapter {
@Autowired
DataSource dataSource;
@Bean
public NamedParameterJdbcTemplate geNamedParameterJdbcTemplate(){
return new NamedParameterJdbcTemplate(dataSource);
}
@Bean
public DataSource getDataSource(){
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost/jack_rutorial_demo");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
@Bean
public InternalResourceViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/jsp/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public ResourceBundleMessageSource messageSource(){
ResourceBundleMessageSource rb = new ResourceBundleMessageSource();
rb.setBasenames(new String[]{"validation"});
return rb;
}
}
Create a WebInitializer class under com.jackrutorial.config package and write the following code in it
package com.jackrutorial.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class[] getRootConfigClasses() {
return new Class[] { WebConfig.class};
}
@Override
protected Class[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
Create a SercurityConfig class under com.jackrutorial.config package and write the following code in it
package com.jackrutorial.config;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import com.jackrutorial.service.LoginServiceImpl;
@Configuration
@EnableWebSecurity
public class SercurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Autowired
LoginServiceImpl loginServiceImpl;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(loginServiceImpl);
auth.authenticationProvider(authenticationProvider());
}
@Bean
public DaoAuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setUserDetailsService(loginServiceImpl);
authenticationProvider.setPasswordEncoder(passwordEncoder());
return authenticationProvider;
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception{
http.csrf().disable();
http.authorizeRequests().antMatchers("/login", "/user/sigup", "/user/register").permitAll();
http.authorizeRequests().antMatchers("/", "/home")
.access("hasRole('ROLE_ADMIN') or hasRole('ROLE_USER')");
http.authorizeRequests().antMatchers("/user/list")
.access("hasRole('ROLE_ADMIN')");
http.authorizeRequests().and().formLogin()
.loginProcessingUrl("/j_spring_security_check")
.loginPage("/login")
.failureUrl("/login?error=true")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutUrl("/j_spring_security_logout").logoutSuccessUrl("/login")
.and().rememberMe()
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(60*60)
.and().exceptionHandling().accessDeniedPage("/accessDenied");
}
@Bean
public PersistentTokenRepository persistentTokenRepository(){
JdbcTokenRepositoryImpl db = new JdbcTokenRepositoryImpl();
db.setDataSource(dataSource);
return db;
}
}
Create a SecurityInitializer class under com.jackrutorial.config package and write the following code in it
package com.jackrutorial.config;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}
Creating Model Layer
Create a UserInfo class under package com.jackrutorial.model and write the following code in itpackage com.jackrutorial.model;
public class UserInfo {
private String username;
private String password;
public UserInfo() {
super();
}
public UserInfo(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Creating Form Layer
Create a UserForm class under package com.jackrutorial.form and write the following code in itpackage com.jackrutorial.form;
public class UserForm {
private String username;
private String password;
private String confirmPassword;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConfirmPassword() {
return confirmPassword;
}
public void setConfirmPassword(String confirmPassword) {
this.confirmPassword = confirmPassword;
}
}
Creating DAO Layer
Create a LoginDao Interface under com.jackrutorial.dao package and write the following code in itpackage com.jackrutorial.dao;
import java.util.List;
import com.jackrutorial.model.UserInfo;
public interface LoginDao {
UserInfo findUserInfo(String username);
List getUserRoles(String username);
}
Create a LoginDaoImpl class implements LoginDao Interface under com.jackrutorial.dao package and write the following code in it
package com.jackrutorial.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import com.jackrutorial.model.UserInfo;
@Repository
public class LoginDaoImpl implements LoginDao {
NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Autowired
public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
public UserInfo findUserInfo(String username) {
String sql = "select username,password from users where username = :username";
UserInfo userInfo = namedParameterJdbcTemplate
.queryForObject(sql, getSqlParameterSource(username, ""), new UserInfoMapper());
return userInfo;
}
private static final class UserInfoMapper implements RowMapper{
public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
String username = rs.getString("username");
String password = rs.getString("password");
return new UserInfo(username, password);
}
}
private SqlParameterSource getSqlParameterSource(String username, String password){
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
parameterSource.addValue("username", username);
parameterSource.addValue("password", password);
return parameterSource;
}
public List getUserRoles(String username) {
String sql = "select role from user_roles where username = :username";
List roles = namedParameterJdbcTemplate
.queryForList(sql, getSqlParameterSource(username, ""), String.class);
return roles;
}
}
Create a UserDao interface under com.jackrutorial.dao package and write the following code in it
package com.jackrutorial.dao;
import java.util.List;
import com.jackrutorial.model.UserInfo;
public interface UserDao {
public List list();
public UserInfo findUserByUsername(String username);
public void update(String username, String password);
public void add(String username, String password);
public boolean userExists(String username);
}
Create a UserDaoImpl class implements UserDao Interface under com.jackrutorial.dao package and write the following code in it
package com.jackrutorial.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import com.jackrutorial.model.UserInfo;
@Repository
public class UserDaoImpl implements UserDao {
NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@Autowired
public void setNamedParameterJdbcTemplate(NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
}
public List list() {
String sql = "select username from users";
List list = namedParameterJdbcTemplate
.query(sql, getSqlParameterSource(null, null), new UserMapper());
return list;
}
private SqlParameterSource getSqlParameterSource(String username, String password){
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
if(username != null){
parameterSource.addValue("username", username);
}
if(password != null){
parameterSource.addValue("password", password);
}
return parameterSource;
}
private static final class UserMapper implements RowMapper{
public UserInfo mapRow(ResultSet rs, int rowNum) throws SQLException {
UserInfo user = new UserInfo();
user.setUsername(rs.getString("username"));
return user;
}
}
public UserInfo findUserByUsername(String username) {
String sql = "select username from users where username = :username";
List list = namedParameterJdbcTemplate
.query(sql, getSqlParameterSource(username, null), new UserMapper());
return list.get(0);
}
public void update(String username, String password) {
String sql = "update users set password = :password where username = :username";
namedParameterJdbcTemplate.update(sql, getSqlParameterSource(username, password));
}
public void add(String username, String password) {
String sql = "insert into users(username, password) values(:username, :password)";
namedParameterJdbcTemplate.update(sql, getSqlParameterSource(username, password));
sql = "insert into user_roles(username, role) values(:username, 'ROLE_USER')";
namedParameterJdbcTemplate.update(sql, getSqlParameterSource(username, password));
}
public boolean userExists(String username) {
String sql = "select * from users where username = :username";
List list = namedParameterJdbcTemplate
.query(sql, getSqlParameterSource(username, null), new UserMapper());
if(list.size() > 0){
return true;
}
return false;
}
}
Creating Service Layer
Create a LoginServiceImpl class implements UserDetailsService Interface under com.jackrutorial.service package and write the following code in itpackage com.jackrutorial.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.jackrutorial.dao.LoginDao;
import com.jackrutorial.model.UserInfo;
@Service
public class LoginServiceImpl implements UserDetailsService {
LoginDao loginDao;
@Autowired
public void setLoginDao(LoginDao loginDao) {
this.loginDao = loginDao;
}
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = loginDao.findUserInfo(username);
if(userInfo == null){
throw new UsernameNotFoundException("username was not found in the database");
}
List roles = loginDao.getUserRoles(username);
List grantList = new ArrayList();
if(roles != null){
for(String role : roles){
GrantedAuthority authority = new SimpleGrantedAuthority(role);
grantList.add(authority);
}
}
UserDetails userDetails = new User(userInfo.getUsername(), userInfo.getPassword(), grantList);
return userDetails;
}
}
Create a UserService Interface under package com.jackrutorial.service package and write the following code in it
package com.jackrutorial.service;
import java.util.List;
import com.jackrutorial.model.UserInfo;
public interface UserService {
public List list();
public UserInfo findUserByUsername(String username);
public void update(String username, String password);
public void add(String username, String password);
public boolean userExists(String username);
}
Create a UserServiceImpl class implements UserService Interface under com.jackrutorial.service package and write the following code in it
package com.jackrutorial.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import com.jackrutorial.dao.UserDao;
import com.jackrutorial.model.UserInfo;
@Service
public class UserServiceImpl implements UserService {
UserDao userDao;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public List list() {
return userDao.list();
}
public UserInfo findUserByUsername(String username) {
return userDao.findUserByUsername(username);
}
public void update(String username, String password) {
userDao.update(username, passwordEncoder.encode(password));
}
public void add(String username, String password) {
userDao.add(username, passwordEncoder.encode(password));
}
public boolean userExists(String username) {
return userDao.userExists(username);
}
}
Custom Validator
Create a SignupValidator class implements Validator Interface under com.jackrutorial.validator package and write the following code in itpackage com.jackrutorial.validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.jackrutorial.form.UserForm;
import com.jackrutorial.service.UserService;
@Component
public class SignupValidator implements Validator {
@Autowired
UserService userService;
public boolean supports(Class clazz) {
return UserForm.class.isAssignableFrom(clazz);
}
public void validate(Object target, Errors errors) {
UserForm user = (UserForm) target;
ValidationUtils.rejectIfEmpty(errors, "username", "notEmpty.username");
ValidationUtils.rejectIfEmpty(errors, "password", "notEmpty.password");
ValidationUtils.rejectIfEmpty(errors, "confirmPassword", "notEmpty.confirmPassword");
if(user.getPassword() != null && user.getConfirmPassword() != null &&
!user.getPassword().equals(user.getConfirmPassword())){
errors.rejectValue("password", "notMatch.confirmPassword");
}
if(userService.userExists(user.getUsername())){
errors.rejectValue("username", "exists.username");
}
}
}
We will define the error codes and their corresponding values in validation.properties file under src/main/resources folder as follows.
notEmpty.username=Username is required notEmpty.password=Password is required notEmpty.confirmPassword=Confirm Password is required notMatch.confirmPassword=Password does not match the confirm password exists.username=username already exists
Creating Controller Layer
Create a LoginController class under package com.jackrutorial.controller package and write the following code in itpackage com.jackrutorial.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping(value="/")
public class LoginController {
@RequestMapping(value="/login", method=RequestMethod.GET)
public ModelAndView login(@RequestParam(value="error", required = false) String error){
ModelAndView model = new ModelAndView();
if(error != null){
model.addObject("msg", "The username or password is incorrect!");
}
model.setViewName("login/login");
return model;
}
@RequestMapping(value={"/", "/home"}, method=RequestMethod.GET)
public ModelAndView home(){
ModelAndView model = new ModelAndView();
model.setViewName("home/home");
return model;
}
@RequestMapping(value="/logout", method=RequestMethod.GET)
public String logoutPage(HttpServletRequest request, HttpServletResponse response){
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if(auth != null){
new SecurityContextLogoutHandler().logout(request, response, auth);
}
return "redirect:/login";
}
@RequestMapping(value="/accessDenied", method=RequestMethod.GET)
public ModelAndView accessDenied(){
ModelAndView model = new ModelAndView();
model.setViewName("errors/access_denied");
return model;
}
}
Create a UserController class under package com.jackrutorial.controller package and add the custom validator in it.
package com.jackrutorial.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.jackrutorial.form.UserForm;
import com.jackrutorial.model.UserInfo;
import com.jackrutorial.service.UserService;
import com.jackrutorial.validator.SignupValidator;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
SignupValidator signupValidator;
@Autowired
UserService userService;
@RequestMapping(value="/list", method=RequestMethod.GET)
public ModelAndView list(){
ModelAndView model = new ModelAndView("user/list");
model.addObject("list", userService.list());
return model;
}
@RequestMapping(value="/changePass/{username}", method=RequestMethod.GET)
public ModelAndView changePass(@PathVariable("username") String username){
ModelAndView model = new ModelAndView("user/change_pass");
model.addObject("user", userService.findUserByUsername(username));
return model;
}
@RequestMapping(value="/save", method=RequestMethod.POST)
public ModelAndView save(@ModelAttribute("user") UserInfo user){
ModelAndView model = changePass(user.getUsername());
userService.update(user.getUsername(), user.getPassword());
model.addObject("msg", "Your password has been changed successfully!");
return model;
}
@RequestMapping(value="/signup", method=RequestMethod.GET)
public ModelAndView signup(){
ModelAndView model = new ModelAndView("user/signup");
model.addObject("userForm", new UserForm());
return model;
}
@RequestMapping(value="/register", method=RequestMethod.POST)
public String register(@ModelAttribute("userForm") UserForm userForm,
BindingResult result, RedirectAttributes redirectAttributes){
signupValidator.validate(userForm, result);
if(result.hasErrors()){
return "/user/signup";
} else {
userService.add(userForm.getUsername(), userForm.getPassword());
redirectAttributes.addFlashAttribute("msg", "Your account has been created successfully!");
return "redirect:/login";
}
}
}
Creating JSP Views
Create login folder under src\main\webapp\WEB-INF\jsp folder.Create login.jsp file under src\main\webapp\WEB-INF\jsp\login folder and write the following code in it.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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 name="loginForm" action='<c:url value="j_spring_security_check" />' method="post" >
<table>
<tr>
<td colspan="2">Login</td>
</tr>
<tr>
<td colspan="2">${msg }</td>
</tr>
<tr>
<td>Username: </td>
<td>
<input type="text" name="username" />
</td>
</tr>
<tr>
<td>Password: </td>
<td>
<input type="password" name="password" />
</td>
</tr>
<tr>
<td>Remember Me: </td>
<td>
<input type="checkbox" name="remember-me" />
</td>
</tr>
<tr>
<td></td>
<td>
<button type="submit">Login</button>
</td>
</tr>
<tr>
<td></td>
<td>
<a href='<c:url value="/user/signup" />'>Sign up</a>
</td>
</tr>
</table>
</form>
</body>
</html>
Create home folder under src\main\webapp\WEB-INF\jsp folder.
Create home.jsp file under src\main\webapp\WEB-INF\jsp\home folder and write the following code in it.
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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>Home</title>
</head>
<body>
<a href='<c:url value="/logout" />'>Logout</a>
<h1>Welcome
<c:if test="${pageContext.request.userPrincipal.name != null }">
${pageContext.request.userPrincipal.name }
</c:if> </h1>
<br/>
<a href='<c:url value="/user/list" />'>Users List</a>
</body>
</html>
Create user folder under src\main\webapp\WEB-INF\jsp folder.
Create signup.jsp file under src\main\webapp\WEB-INF\jsp\user folder and write the following code in it.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!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>Signup</title>
</head>
<body>
<spring:url value="/user/register" var="registerURL" />
<form:form action="${registerURL}" modelAttribute="userForm" method="post" >
<label>Username: </label>
<form:input path="username" type="text" />
<form:errors path="username" />
<br/>
<label>Password: </label>
<form:password path="password" />
<form:errors path="password" />
<br/>
<label>Confirm Password: </label>
<form:password path="confirmPassword" />
<form:errors path="confirmPassword" />
<br/>
<button type="submit">Sign up</button>
</form:form>
</body>
</html>
Create list.jsp file under src\main\webapp\WEB-INF\jsp\user folder and write the following code in it.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<!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>Users List</title>
</head>
<body>
<a href='<c:url value="/logout" />'>Logout</a>
<br/>
<table border="1">
<tr>
<td>Username</td>
<td>Action</td>
</tr>
<c:forEach items="${list }" var="user">
<tr>
<td>${user.username }</td>
<td>
<spring:url value="/user/changePass" var="changePassURL" />
<a href="${changePassURL }/${user.username }">Change Pass</a>
</td>
</tr>
</c:forEach>
</table>
</body>
</html>
Create change_pass.jsp file under src\main\webapp\WEB-INF\jsp\user folder and write the following code in it.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!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>Change Password</title>
</head>
<body>
<spring:url value="/user/save" var="saveURL" />
<form:form method="post" modelAttribute="user" action="${saveURL }">
<form:hidden path="username"/>
<table border="1">
<tr>
<td colspan="2">${msg }</td>
</tr>
<tr>
<td>Username: </td>
<td>${user.username }</td>
</tr>
<tr>
<td>Password: </td>
<td><form:password path="password" /></td>
</tr>
<tr>
<td></td>
<td>
<button type="submit" >Change Password</button>
</td>
</tr>
</table>
</form:form>
</body>
</html>
Create errors folder under src\main\webapp\WEB-INF\jsp folder.
Create access_denied.jsp file under src\main\webapp\WEB-INF\jsp\errors folder and write the following code in it.
<%@ 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>Access denied</title>
</head>
<body>
<h1>Access denied!</h1>
</body>
</html>
Building
- Right click this project
- Select Run As -> Maven clean
- Right click this project
- Select Run As -> Maven install
Configuring Apache Tomcat
- Under Servers tab, click link "No servers are available. Click this link to create a new server ...", select Apache tomcat 7
- Click Finish
- Right click "Tomcat v7.0 Server at localhost [Stopped, Republish]", select "Add and Remove ..."
- Add SpringMVCSignupLoginPasswordEncoder project, then Click Finish
- Open server.xml file under Servers Folder
- Find line
Update its as below:
<Context docBase="<Project Folder Location>\SpringMVCSignupLoginPasswordEncoder\target\SpringMVCSignupLoginPasswordEncoder-0.0.1-SNAPSHOT\" path="/SpringMVCSignupLoginPasswordEncoder" reloadable="true" />
- Copy mysql-connector-java-5.1.45-bin.jar file to <Apache Tomcat Folder Location>\apache-tomcat-7.0.68\lib\
Watch video add Apache Tomcat Server in Eclipse IDE
Run application & Check result
- Start Apache Tomcat from Eclipse IDE.
- Type the following URLs in browser's address bar to open the login from.
http://localhost:8080/SpringMVCSignupLoginPasswordEncoder/
Enter username/password: admin/123 to login







