Пример CRUD Restful Web Service c Spring Boot
View more Tutorials:
Статья основана на:
-
Spring Boot 2.x
-
Eclipse 4.7 Oxygen
Смотрите также:
В данной статье я покажу вам как создать приложение Restful Web Service используя Spring Boot, и имея 4 функции Create, Read, Update, Delete (CRUD).
Read (GET method)
Мы построим URI, которому назначено (designated) вернуть пользователю список сотрудников (employee). И определить другой URI чтобы вернуть пользователю информацию определенного сотрудника. Данные, которые получит пользователь будут в формате XML или JSON. Эти URI принимают только request с методом GET.
- GET http://localhost:8080/employees
- GET http://localhost:8080/employee/E01
Update (PUT method).
Построить URI для обработки запроса (request) редактирования информации сотрудника (employee). Данный URI принимает только request с методом PUT. Данные прикрепленные вместе с request являются новой информацией сотрудника, имеют формат XML или JSON.
- PUT http://localhost:8080/employee
Create (POST method)
Построить URI для обработки запроса (request) создать нового сотрудника (employee). Данный URI принимает только request с методом POST. Данные отправленные с прикрепленным запросом являются информацией сотрудника, который будет создан, имеет формат XML или JSON.
- POST http://localhost:8080/employee
Delete (DELETE method).
Построить URI для обработки запроса (request) удалить сотрудника (employee). Данный URI принимает только request с методом DELETE.
Примечание: Нет данных прикрепленных с request в данном случае (Как данные прикрепленные по методу POST), так как request с методом DELETE не может прикрепить данные. Информация сотрудника, которого нужно удалить находится на URI или на QueryString у URL.
- DELETE http://localhost:8080/employee/{empNo}
На Eclipse выбрать:
- File/New/Other..

Ввести:
- Name: SpringBootCrudRestful
- Group: org.o7planning
- Package: org.o7planning.sbcrudrestful

Следующий шаг, вам нужно выбрать технологии использования.


OK, Project создан.

В данном примере нам нужна библиотека для конвертирования (convert) XML в объект Java и обратно. И другая библиотека для конвертирования JSON в Java и обратно.
JSON <==> Java
spring-boot-starter-web имеет готовую библиотеку jackson-databind, данная библиотека помогает конвертировать JSON в объект Java и обратно.

XML <==> Java
Spring Boot использует JAXB (Готовый в JDK) как библиотеку по умолчанию для конвертирования XML и Java. Но ваши классы Java должны быть аннотированы (annotated) с помощью @XmlRootElement,... Поэтому мой совет вам стоит использовать jackson-dataformat-xml как библиотеку для конвертирования XML и Java. Чтобы использовать jackson-dataformat-xml вам нужно объявить его в файле pom.xml:
** pom.xml **
... <dependencies> ... <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency> ... </dependencies> ...


pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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>org.o7planning</groupId> <artifactId>SpringBootCrudRestful</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringBootCrudRestful</name> <description>Spring Boot + Restful</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>

SpringBootCrudRestfulApplication.java
package org.o7planning.sbcrudrestful; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootCrudRestfulApplication { public static void main(String[] args) { SpringApplication.run(SpringBootCrudRestfulApplication.class, args); } }
Класс Employee представляет сотрудника.
Employee.java
package org.o7planning.sbcrudrestful.model; public class Employee { private String empNo; private String empName; private String position; 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 аннотирован (annotate) с помощью @Repository чтобы оповестить Spring что он является Spring BEAN. Данный класс включает методы, помогающие дать запрос на список сотрудников (employee), создать сотрудника, изменить информацию сотрудника, и удалить сотрудника.
EmployeeDAO.java
package org.o7planning.sbcrudrestful.dao; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.o7planning.sbcrudrestful.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; } }
Класс MainRESTController аннотирован (annotate) с помощью @RestController, чтобы оповестить Spring, что он является Spring Restful Controller,
MainRESTController.java
package org.o7planning.sbcrudrestful.controller; import java.util.List; import org.o7planning.sbcrudrestful.dao.EmployeeDAO; import org.o7planning.sbcrudrestful.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/SomeContextPath/employees // http://localhost:8080/SomeContextPath/employees.xml // http://localhost:8080/SomeContextPath/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/SomeContextPath/employee/{empNo} // http://localhost:8080/SomeContextPath/employee/{empNo}.xml // http://localhost:8080/SomeContextPath/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/SomeContextPath/employee // http://localhost:8080/SomeContextPath/employee.xml // http://localhost:8080/SomeContextPath/employee.json @RequestMapping(value = "/employee", // method = RequestMethod.POST, // produces = { MediaType.APPLICATION_JSON_VALUE, // MediaType.APPLICATION_XML_VALUE }) @ResponseBody public Employee addEmployee(@RequestBody Employee emp) { System.out.println("(Service Side) Creating employee: " + emp.getEmpNo()); return employeeDAO.addEmployee(emp); } // URL: // http://localhost:8080/SomeContextPath/employee // http://localhost:8080/SomeContextPath/employee.xml // http://localhost:8080/SomeContextPath/employee.json @RequestMapping(value = "/employee", // method = RequestMethod.PUT, // produces = { MediaType.APPLICATION_JSON_VALUE, // MediaType.APPLICATION_XML_VALUE }) @ResponseBody public Employee updateEmployee(@RequestBody Employee emp) { System.out.println("(Service Side) Editing employee: " + emp.getEmpNo()); return employeeDAO.updateEmployee(emp); } // URL: // http://localhost:8080/SomeContextPath/employee/{empNo} @RequestMapping(value = "/employee/{empNo}", // method = RequestMethod.DELETE, // produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }) @ResponseBody public void deleteEmployee(@PathVariable("empNo") String empNo) { System.out.println("(Service Side) Deleting employee: " + empNo); employeeDAO.deleteEmployee(empNo); } }
Объяснение:
- produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }
- produces = { "application/json" , "application/xml" }
Атрибут produces используется чтобы определить URL который будет создавать только (возвращать пользователю) данные с какими форматами. Например "application/json", "application/xml".
Чтобы запустить приложение, нажмите на правую кнопку мыши на Project и выберите:
- Run As/Spring Boot App


После запуска приложения, вы можете протестировать его функции.
Test GET:
If ERROR==> Please use Spring Boot 2.0.0.M5 temporarily.(And wait for the official version of Spring Boot 2).<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.M5</version> <relativePath/> <!-- lookup parent from repository --> </parent>
Чтобы получить список сотрудников (employee), пользователю нужно отправить request (запрос) с методом GET. Вы можете легко протестировать данную функцию используя браузер.

Или:


Как создать request используя метод POST, PUT или DELETE?
Чтобы создать request (запрос) с методом POST, PUT или DELETE вам нужно использовать инструмент, как например RestClient, cURL,.. или написать ваше собственное приложение Rest Client.Смотрите так же:
Test POST
Чтобы создать сотрудника (employee), вам нужно создать request с методом POST, и прикрепить с информацией сотрудника, который будет создан, отправленные данные имеют формат JSON или XML:
POST http://localhost:8080/employee Acept: application/xml <Employee> <empNo>E11</empNo> <empName>New Employee</empName> <position>Clerk</position> </Employee>
POST http://localhost:8080/employee Acept: application/json {"empNo":"E11","empName":"New Employee","position":"Clerk"}