Простой пример CRUD с Spring MVC RESTful Web Service
1. Цель статьи
В данной статье я покажу вам как создать приложение RESTful Web service с Spring MVC.
Для начала, вам стоит изучить "Что такое RESTful Web Service?":
Заметьте что у вас есть много способов создать приложение RESTful Web Service, один из этих способов это использовать JAX-RS, Spring Boot вы можете посмотреть связанные инструкции здесь:
2. XML-Binding & JSON-Binding
JAVA <==> JSON
Spring MVC нужно JSON-Binding чтобы конвертировать объект Java в JSON и обратно. И вы можете использовать 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 нужен XML-Binding чтобы конвертировать объект Java в XML, в данном случае у вас есть 2 способа.
- Использовать Jackson: jackson-dataformat-xml
- Или использовать JAXB
-
- JAXB (Java Architecture for XML Binding): Это интегрированная библиотека в стандартную Java с версии 1.6.
- jackson-dataformat-xml: Это расширенная библиотека 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 конвертирует объект Java в XML без прикрепленных Annotation в классы model.
- JAXB (Java Architecture for XML Binding): Java ==> XML
В случае если вы хотите чтобы Spring MVC использовал JAXB как XML-Binding по умолчанию. Вам нужно использовать @XmlRootElement для аннотации на классах model.
В данной статье я использую библиотеку Jackson для конвертации объектов Java на XML и 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. Конфигурация web.xml & pom.xml
Использовать 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. Конфигурация 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 симулирует получение данных из ресурсов данных, и процессирует 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 использует @RestController для аннотации в классе, этот класс будет 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. Запуск приложения
- Name: Run SpringMVCRESTful
- Base directory: ${workspace_loc:/SpringMVCRESTful}
- Goals: tomcat7:run
Чтобы протестировать insert, update, delete (удалить) данные на RESTful web service, вам нужно использовать инструмент RESTClient, это Addons для Firefox и Chrome, вы можете посмотреть инструкцию установки и использования по ссылке:
Руководства Java Web Services
- Что такое RESTful Web Service?
- Руководство Java RESTful Web Services для начинающих
- Простой пример CRUD с Java RESTful Web Service
- Создайте Java RESTful Client с помощью Jersey Client
- Отладчик RESTClient для RESTful WebServices
- Простой пример CRUD с Spring MVC RESTful Web Service
- Пример CRUD Restful Web Service c Spring Boot
- Пример Spring Boot Restful Client c RestTemplate
- Защита Spring Boot RESTful Service используя Basic Authentication
Show More
Руководства Spring MVC
- Руководство Spring для начинающих
- Установите Spring Tool Suite для Eclipse
- Руководство Spring MVC для начинающих
- Настроить статические ресурсы в Spring MVC
- Руководство Spring MVC Interceptor
- Создание многоязычного веб-приложения с использованием Spring MVC
- Руководство Spring MVC File Upload/Download
- Простой веб-приложение Java с использованием Spring MVC, Spring Security и Spring JDBC
- Социальный вход в Spring MVC с Spring Social Security
- Руководство Spring MVC и FreeMarker
- Используйте Template в Spring MVC с Apache Tiles
- Используйте несколько DataSources в Spring MVC
- Руководство Spring MVC Form и Hibernate
- Запускать фоновые запланированные задачи в Spring
- Создание Java Корзина веб-приложения с использованием Spring MVC и Hibernate
- Простой пример CRUD с Spring MVC RESTful Web Service
- Развертывание Spring MVC на сервере Oracle WebLogic Server
Show More