Till now we have created CRUD database service for the domain class “User” and also integrated MyBatis configuration with Spring Configuration file. Next, we will create an web page using Spring MVC to use MyBatis CRUD service to perform operations to database.
So, in this part we will go through following sessions that will make us able to create the user interface for the example using Spring MVC and MyBatis CRUD service:
- The Spring Form Validator
- The Spring MVC Controller
- The jsp page and JavaScript files used to perform UI creation
- And the last Spring MVC configuration file
package com.raistudies.validator;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.raistudies.domain.User;
@Component
public class RegistrationValidator implements Validator {
public boolean supports(Class<?> c) {
return User.class.isAssignableFrom(c);
}
public void validate(Object command, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "field.name.empty");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "standard", "field.standard.empty");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "age", "field.age.empty");
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "sex", "field.sex.empty");
User usrBean = (User)command;
if(!isNumber(usrBean.getAge().trim()))
errors.rejectValue("age", "field.age.NAN");
}
private boolean isNumber(String str){
for (int i = 0; i < str.length(); i++) {
//If we find a non-digit character we return false.
if (!Character.isDigit(str.charAt(i)))
return false;
}
return true;
}
}
field.name.empty=Name field is mandatory. field.standard.empty=Standard field is mandatory. field.age.empty=Age field is mandatory. field.sex.empty=Sex field is mandatory. field.age.NAN=Age should be a number.
package com.raistudies.controllers;
import java.util.List;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
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.raistudies.domain.User;
import com.raistudies.persistence.UserService;
import com.raistudies.validator.RegistrationValidator;
@Controller
@RequestMapping(value="/registration")
public class RegistrationController {
private RegistrationValidator validator = null;
private UserService userService = null;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
public RegistrationValidator getValidator() {
return validator;
}
@Autowired
public void setValidator(RegistrationValidator validator) {
this.validator = validator;
}
@RequestMapping(method=RequestMethod.GET)
public String showForm(ModelMap model){
List<User> users = userService.getAllUser();
model.addAttribute("users", users);
User user = new User();
user.setId(UUID.randomUUID().toString());
model.addAttribute("user", user);
return "registration";
}
@RequestMapping(value="/add", method=RequestMethod.POST)
public ModelAndView add(@ModelAttribute(value="user") User user,BindingResult result){
validator.validate(user, result);
ModelAndView mv = new ModelAndView("registration");
if(!result.hasErrors()){
userService.saveUser(user);
user = new User();
user.setId(UUID.randomUUID().toString());
mv.addObject("user", user);
}
mv.addObject("users", userService.getAllUser());
return mv;
}
@RequestMapping(value="/update", method=RequestMethod.POST)
public ModelAndView update(@ModelAttribute(value="user") User user,BindingResult result){
validator.validate(user, result);
ModelAndView mv = new ModelAndView("registration");
if(!result.hasErrors()){
userService.updateUser(user);
user = new User();
user.setId(UUID.randomUUID().toString());
mv.addObject("user", user);
}
mv.addObject("users", userService.getAllUser());
return mv;
}
@RequestMapping(value="/delete", method=RequestMethod.POST)
public ModelAndView delete(@ModelAttribute(value="user") User user,BindingResult result){
validator.validate(user, result);
ModelAndView mv = new ModelAndView("registration");
if(!result.hasErrors()){
userService.deleteUser(user.getId());
user = new User();
user.setId(UUID.randomUUID().toString());
mv.addObject("user", user);
}
mv.addObject("users", userService.getAllUser());
return mv;
}
}
The controller is using two beans for the CRUD operations, one is RegistrationValidator that we say above to validate the form data and other is UserService that we created in our previous part using MyBatis 3 to perform database operations on the form data. Both the beans will be auto wired by spring using setter injection.
The controller have following operation methods that handles CRUD requests on form data:
- showForm() : This operations will show up the form for the first time that is why we have put method type as RequestMethod.GET The method will also provide all available users in database using getAllUser() method of UserService to show up on the table bellow the form.
- add() : This operation will handle the create operation. First of all it will validate the form data and if no error occur then it will save form data to database to create a new user using saveUser() method of UserService. It will also bind a new User object with the form.
- update() : update method will update the user detail to the database using updateUser() method of UserService and before that it will validate the data using RegistrationValidator.
- delete() : This method is used to delete the user from database and take helps from the deleteUser() method of UserService for this.
Spring MVC and MyBatis 3 Integration - User Form
UI functionality:
- The “Save Changes” button will be used to create a new user or to update an existing user.
- The “New User” button will be used to set the form to create a new user.
- The “Delete User” button will be used to delete a user who’s details are showing in the form
- Clicking on any row will bring the corresponding row data to form fields for update or delete.
</div>
<div>
<pre><!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ page session="true" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello World with Spring 3 MVC</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<script type="text/javascript" src='<c:url value="/resources/common.js"/>'></script>
<script type="text/javascript" src='<c:url value="/resources/registration.js"/>'></script>
<script type="text/javascript">
var projectUrl = '<c:url value="/"/>';
if(projectUrl.indexOf(";", 0) != -1){
projectUrl = projectUrl.substring(0, projectUrl.indexOf(";", 0));
}
</script>
</head>
<body>
<fieldset>
<legend>Registration Form</legend>
<center>
<form:form commandName="user" action="/SpringMVCMyBatisCRUDExample/app/registration/add" name="userForm">
<form:hidden path="id"/>
<table>
<tr><td colspan="2" align="left"><form:errors path="*" cssStyle="color : red;"/></td></tr>
<tr><td>Name : </td><td><form:input path="name" /></td></tr>
<tr><td>Standard : </td><td><form:input path="standard" /></td></tr>
<tr><td>Age : </td><td><form:input path="age" /></td></tr>
<tr><td>Sex : </td><td><form:select path="sex">
<form:option value="Male"/>
<form:option value="Female"/>
</form:select></td></tr>
<tr><td colspan="2"><input type="submit" value="Save Changes"/>
<input type="reset" name="newUser" value="New User" onclick="setAddForm();" disabled="disabled"/>
<input type="submit" name="deleteUser" value="Delete User" onclick="setDeleteForm();" disabled="disabled"/></td></tr>
</table>
</form:form>
</center>
</fieldset>
<c:if test="${!empty users}">
<br />
<center>
<table width="90%">
<tr style="background-color: gray;">
<th>Name</th>
<th>Standard</th>
<th>Age</th>
<th>Sex</th>
</tr>
<c:forEach items="${users}" var="user">
<tr style="background-color: silver;" id="${user.id}" onclick="setUpdateForm('${user.id}');">
<td><c:out value="${user.name}"/></td>
<td><c:out value="${user.standard}"/></td>
<td><c:out value="${user.age}"/></td>
<td><c:out value="${user.sex}"/></td>
</tr>
</c:forEach>
</table>
</center>
<br />
</c:if>
</body>
</html></pre>
</div>
<div>
</div>
<div>
<pre><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- Application Message Bundle -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="/WEB-INF/messages" />
<property name="cacheSeconds" value="3000" />
</bean>
<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="com.raistudies" />
<!-- Configures the @Controller programming model -->
<mvc:annotation-driven />
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<import resource="jdbc-context.xml"/>
</beans></pre>
</div>
<div>
The configuration file includes the messages.properties as resource bundle and also include jdbc-context.xml configuration files which contains configuration for integration MyBatis 3 with Spring.
While running the example you will get the above screen as out put that will also show all the records present in database. Click on the “Save Changes” button you will get following screen that will show you validation errors on the blank form values:
Spring MVC and MyBatis 3 Integration - User Form with validation errors
Now fill the form with valid data and and click on the “Save Changes” button, it will bring the form data to bellow table.
That is all from this example. Hope that you have enjoyed the learning!! ![]()
You can download the source code and war file from following links:
Source (Eclipse Project without jars) : Download
War (With jars) : Download
Nice write up when I try and build/ or just deploy the war file in Tomcat 6.0.32 <I get stopped with java.lang.NoClassDefFoundError: javax/servlet/AsyncListener . looks like the servlet-api.jar packages with tomcat wont do. I figured we need we need javax.servlet.jar (servlet 3) – once I pop that in Spring starts giving errors – any ideas ?