Simple CRUD example with Spring MVC RESTful Web Service
1. The objective of the document
In the post, I will show you the way to create a RESTful Web service application with Spring MVC.
First of all, you should find out "What is RESTful Web Services?":
Note that there are a lot of ways to create a RESTful Web Service application, one of which is to use JAX-RS, Spring Boot, you can see relevant guides here:
2. XML-Binding & JSON-Binding
JAVA <==> JSON
Spring MVC need a JSON-Binding to convert Java object into JSON and vice versa. And you can use Jackson (jackson-databind).
<!-- MAVEN -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.3</version>
</dependency>
JAVA <==> XML:
Spring MVC needs a XML-Binding to convert a Java object into XML, in case you have two choices.
- Use Jackson: jackson-dataformat-xml
- Or use JAXB
-
- JAXB (Java Architecture for XML Binding) - Is a library integrated into Java Standard Edition from version 1.6.
- jackson-dataformat-xml: Is a extended library of Jackson.
<!-- jackson-dataformat-xml -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.3</version>
</dependency>
- Jackson: Java Object ==> XML
jackson-dataformat-xml converts a Java object into XML without Annotation attached to the model classes.
- JAXB (Java Architecture for XML Binding): Java ==> XML
In case that you want Spring MVC to use JAXB as a default XML-Binding. You need to use @XmlRootElement to annotate in model classes.
In the post, I will use Jackson library to convert Java objects into XML and JSON.
<!-- JSON-Binding -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.3</version>
</dependency>
<!-- XML-Binding -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.3</version>
</dependency>
4. Configure web.xml & pom.xml
Using Web App >= 3.
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_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>SpringMVCRESTful</display-name>
</web-app>
Maven:
pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.o7planning</groupId>
<artifactId>SpringMVCRESTful</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>SpringMVCRESTful Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Servlet Library -->
<!-- http://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- Spring dependencies -->
<!-- http://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<!-- http://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.dataformat/jackson-dataformat-xml -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.3</version>
</dependency>
</dependencies>
<build>
<finalName>SpringMVCRESTful</finalName>
<plugins>
<!-- Config: Maven Tomcat Plugin -->
<!-- http://mvnrepository.com/artifact/org.apache.tomcat.maven/tomcat7-maven-plugin -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<!-- Config: contextPath and Port (Default: /SpringMVCRESTful : 8080) -->
<!--
<configuration>
<path>/</path>
<port>8899</port>
</configuration>
-->
</plugin>
</plugins>
</build>
</project>
5. Configure Spring MVC
SpringWebAppInitializer.java
package org.o7planning.springmvcrestful.config;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;
public class SpringWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext();
appContext.register(ApplicationContextConfig.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("SpringDispatcher",
new DispatcherServlet(appContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
// UTF8 Charactor Filter.
FilterRegistration.Dynamic fr = servletContext.addFilter("encodingFilter", CharacterEncodingFilter.class);
fr.setInitParameter("encoding", "UTF-8");
fr.setInitParameter("forceEncoding", "true");
fr.addMappingForUrlPatterns(null, true, "/*");
}
}
ApplicationContextConfig.java
package org.o7planning.springmvcrestful.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("org.o7planning.springmvcrestful.*")
public class ApplicationContextConfig {
// No need ViewSolver
// Other declarations if needed ...
}
WebMvcConfig.java
package org.o7planning.springmvcrestful.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
6. Data Model
Employee.java
package org.o7planning.springmvcrestful.model;
public class Employee {
private String empNo;
private String empName;
private String position;
// This default constructor is required if there are other constructors.
public Employee() {
}
public Employee(String empNo, String empName, String position) {
this.empNo = empNo;
this.empName = empName;
this.position = position;
}
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
}
EmployeeDAO class simulate retrieving data from a data source, and process insert, update, delete.
EmployeeDAO.java
package org.o7planning.springmvcrestful.dao;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.o7planning.springmvcrestful.model.Employee;
import org.springframework.stereotype.Repository;
@Repository
public class EmployeeDAO {
private static final Map<String, Employee> empMap = new HashMap<String, Employee>();
static {
initEmps();
}
private static void initEmps() {
Employee emp1 = new Employee("E01", "Smith", "Clerk");
Employee emp2 = new Employee("E02", "Allen", "Salesman");
Employee emp3 = new Employee("E03", "Jones", "Manager");
empMap.put(emp1.getEmpNo(), emp1);
empMap.put(emp2.getEmpNo(), emp2);
empMap.put(emp3.getEmpNo(), emp3);
}
public Employee getEmployee(String empNo) {
return empMap.get(empNo);
}
public Employee addEmployee(Employee emp) {
empMap.put(emp.getEmpNo(), emp);
return emp;
}
public Employee updateEmployee(Employee emp) {
empMap.put(emp.getEmpNo(), emp);
return emp;
}
public void deleteEmployee(String empNo) {
empMap.remove(empNo);
}
public List<Employee> getAllEmployees() {
Collection<Employee> c = empMap.values();
List<Employee> list = new ArrayList<Employee>();
list.addAll(c);
return list;
}
}
7. Spring REST Controller
Spring uses @RestController to annotate in a class, the class will be a RESTful Controller.
MainRESTController.java
package org.o7planning.springmvcrestful.controller;
import java.util.List;
import org.o7planning.springmvcrestful.dao.EmployeeDAO;
import org.o7planning.springmvcrestful.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainRESTController {
@Autowired
private EmployeeDAO employeeDAO;
@RequestMapping("/")
@ResponseBody
public String welcome() {
return "Welcome to RestTemplate Example.";
}
// URL:
// http://localhost:8080/SpringMVCRESTful/employees
// http://localhost:8080/SpringMVCRESTful/employees.xml
// http://localhost:8080/SpringMVCRESTful/employees.json
@RequestMapping(value = "/employees", //
method = RequestMethod.GET, //
produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
@ResponseBody
public List<Employee> getEmployees() {
List<Employee> list = employeeDAO.getAllEmployees();
return list;
}
// URL:
// http://localhost:8080/SpringMVCRESTful/employee/{empNo}
// http://localhost:8080/SpringMVCRESTful/employee/{empNo}.xml
// http://localhost:8080/SpringMVCRESTful/employee/{empNo}.json
@RequestMapping(value = "/employee/{empNo}", //
method = RequestMethod.GET, //
produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
@ResponseBody
public Employee getEmployee(@PathVariable("empNo") String empNo) {
return employeeDAO.getEmployee(empNo);
}
// URL:
// http://localhost:8080/SpringMVCRESTful/employee
// http://localhost:8080/SpringMVCRESTful/employee.xml
// http://localhost:8080/SpringMVCRESTful/employee.json
@RequestMapping(value = "/employee", //
method = RequestMethod.POST, //
produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
@ResponseBody
public Employee addEmployee(@RequestBody Employee emp) {
return employeeDAO.addEmployee(emp);
}
// URL:
// http://localhost:8080/SpringMVCRESTful/employee
// http://localhost:8080/SpringMVCRESTful/employee.xml
// http://localhost:8080/SpringMVCRESTful/employee.json
@RequestMapping(value = "/employee", //
method = RequestMethod.PUT, //
produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
@ResponseBody
public Employee updateEmployee(@RequestBody Employee emp) {
return employeeDAO.updateEmployee(emp);
}
// URL:
// http://localhost:8080/SpringMVCRESTful/employee/{empNo}
@RequestMapping(value = "/employees/{empNo}", //
method = RequestMethod.DELETE, //
produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
@ResponseBody
public void deleteEmployee(@PathVariable("empNo") String empNo) {
employeeDAO.deleteEmployee(empNo);
}
}
8. Running apps
- Name: Run SpringMVCRESTful
- Base directory: ${workspace_loc:/SpringMVCRESTful}
- Goals: tomcat7:run
In order to test insert, update and delete data on RESTful web service, you need to use RESTClient tool which is an Addons for Firefox and Chrome, you can see the installation & use guide here:
Java Web Services Tutorials
- What are RESTful Web Services?
- Java RESTful Web Services Tutorial for Beginners
- Simple CRUD example with Java RESTful Web Service
- Create Java RESTful Client with Jersey Client
- RESTClient A Debugger for RESTful Web Services
- Simple CRUD example with Spring MVC RESTful Web Service
- CRUD Restful Web Service Example with Spring Boot
- Spring Boot Restful Client with RestTemplate Example
- Secure Spring Boot RESTful Service using Basic Authentication
Show More
Spring MVC Tutorials
- Spring Tutorial for Beginners
- Install Spring Tool Suite for Eclipse
- Spring MVC Tutorial for Beginners - Hello Spring 4 MVC
- Configure Static Resources in Spring MVC
- Spring MVC Interceptors Tutorial with Examples
- Create a Multiple Languages web application with Spring MVC
- Spring MVC File Upload Tutorial with Examples
- Simple Login Java Web Application using Spring MVC, Spring Security and Spring JDBC
- Spring MVC Security with Hibernate Tutorial with Examples
- Spring MVC Security and Spring JDBC Tutorial (XML Config)
- Social Login in Spring MVC with Spring Social Security
- Spring MVC and Velocity Tutorial with Examples
- Spring MVC and FreeMarker Tutorial with Examples
- Use Template in Spring MVC with Apache Tiles
- Spring MVC and Spring JDBC Transaction Tutorial with Examples
- Use Multiple DataSources in Spring MVC
- Spring MVC and Hibernate Transaction Tutorial with Examples
- Spring MVC Form Handling and Hibernate Tutorial with Examples
- Run background scheduled tasks in Spring
- Create a Java Shopping Cart Web Application using Spring MVC and Hibernate
- Simple CRUD example with Spring MVC RESTful Web Service
- Deploy Spring MVC on Oracle WebLogic Server
Show More