Springboot教程:Springboot 2 REST API示例
1. Maven依赖
首先,创建一个简单的maven Web项目并更新pom.xml
文件中的spring boot依赖项。
重要的依赖关系是spring-boot-starter-parent
和spring-boot-starter-web
。Starter Web依赖关系可传递地包含更多依赖关系来构建Web应用程序,例如spring-webmvc,spring-web,hibernate-validator,tomcat-embed-core,tomcat-embed-el,tomcat-embed-websocket,jackson-databind,jackson- datatype-jdk8,jackson-datatype-jsr310和jackson-module-parameter-names。
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?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>com.howtodoinjava.demo</groupId> <artifactId>springbootdemo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringBootDemo</name> <description>Spring Boot2 REST API Demo for http://howtodoinjava.com</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath /> </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>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> |
<groupId>com.howtodoinjava.demo</groupId>
<artifactId>springbootdemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringBootDemo</name>
<description>Spring Boot2 REST API Demo for http://howtodoinjava.com</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath />
</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>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>
2. Spring Boot 2 REST API控制器
- 在Spring中,一个能够提供REST API请求的控制器类称为rest控制器。它应该使用@RestController注释进行注释。
- 资源在@RequestMapping注释中指定。它可以在类级别和方法级别应用。添加类级别路径和方法级别路径后,将解析API的完整URI。
- 我们应该总是编写produces 和consumes 属性来指定API的mediatype属性。
在给定的控制器中,我们有两种API方法。可以 根据需要添加更多方法。
- HTTP GET / employees - 返回employees列表。
- HTTP POST / employees - 在employees集合中添加employe。
EmployeeController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package com.howtodoinjava.rest.controller; import java.net.URI; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import com.howtodoinjava.rest.dao.EmployeeDAO; import com.howtodoinjava.rest.model.Employee; import com.howtodoinjava.rest.model.Employees; @RestController @RequestMapping(path = "/employees") public class EmployeeController { @Autowired private EmployeeDAO employeeDao; @GetMapping(path="/", produces = "application/json") public Employees getEmployees() { return employeeDao.getAllEmployees(); } @PostMapping(path= "/", consumes = "application/json", produces = "application/json") public ResponseEntity<Object> addEmployee(@RequestBody Employee employee) { Integer id = employeeDao.getAllEmployees().getEmployeeList().size() + 1; employee.setId(id); employeeDao.addEmployee(employee); URI location = ServletUriComponentsBuilder.fromCurrentRequest() .path("/{id}") .buildAndExpand(employee.getId()) .toUri(); return ResponseEntity.created(location).build(); } } |
import java.net.URI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import com.howtodoinjava.rest.dao.EmployeeDAO;
import com.howtodoinjava.rest.model.Employee;
import com.howtodoinjava.rest.model.Employees;
@RestController
@RequestMapping(path = "/employees")
public class EmployeeController
{
@Autowired
private EmployeeDAO employeeDao;
@GetMapping(path="/", produces = "application/json")
public Employees getEmployees()
{
return employeeDao.getAllEmployees();
}
@PostMapping(path= "/", consumes = "application/json", produces = "application/json")
public ResponseEntity<Object> addEmployee(@RequestBody Employee employee)
{
Integer id = employeeDao.getAllEmployees().getEmployeeList().size() + 1;
employee.setId(id);
employeeDao.addEmployee(employee);
URI location = ServletUriComponentsBuilder.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(employee.getId())
.toUri();
return ResponseEntity.created(location).build();
}
}
我们可以使用application.properties
文件控制和自定义大量实现细节。但是为了简化这个演示,我将它留空。
3. @SpringBootApplication
我们的REST API框架已准备就绪。现在我们需要配置Spring来检测我们的其他控制器(使用自动扫描)并在嵌入式tomcat服务器中部署apis。值得庆幸的是,Spring boot通过使用自动配置的概念使所有这些事情变得非常简单。
自动配置尝试猜测和配置您可能需要的bean。自动配置类通常基于应用程序类路径中的jar和我们在@Configuration类中另外定义的bean来应用。
在这种情况下,它会做一些事情。
- 它检测spring-webmvc,因此配置默认的spring mvc应用程序bean。它有助于扫描和配置
@RestController
以及类似的注释。 - 它检测嵌入式tomcat jar,为我们配置嵌入式tomcat。
- 它检测JSON jar,以便为API配置JSON支持。
SpringBootDemoApplication.java
1 2 3 4 5 6 7 8 9 10 11 12 |
package com.howtodoinjava.rest; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootDemoApplication { public static void main(String[] args) { SpringApplication.run(SpringBootDemoApplication.class, args); } } |
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
4.Model classes and DAO
这些类与REST没有直接关系。还是让我们来看看他们是如何写的。
Employee.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package com.howtodoinjava.rest.model; public class Employee { public Employee() { } public Employee(Integer id, String firstName, String lastName, String email) { super(); this.id = id; this.firstName = firstName; this.lastName = lastName; this.email = email; } private Integer id; private String firstName; private String lastName; private String email; //Getters and setters @Override public String toString() { return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]"; } } |
public class Employee {
public Employee() {
}
public Employee(Integer id, String firstName, String lastName, String email) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
private Integer id;
private String firstName;
private String lastName;
private String email;
//Getters and setters
@Override
public String toString() {
return "Employee [id=" + id + ", firstName=" + firstName + ",
lastName=" + lastName + ", email=" + email + "]";
}
}
Employees.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com.howtodoinjava.rest.model; import java.util.ArrayList; import java.util.List; public class Employees { private List<Employee> employeeList; public List<Employee> getEmployeeList() { if(employeeList == null) { employeeList = new ArrayList<>(); } return employeeList; } public void setEmployeeList(List<Employee> employeeList) { this.employeeList = employeeList; } } |
import java.util.ArrayList;
import java.util.List;
public class Employees
{
private List<Employee> employeeList;
public List<Employee> getEmployeeList() {
if(employeeList == null) {
employeeList = new ArrayList<>();
}
return employeeList;
}
public void setEmployeeList(List<Employee> employeeList) {
this.employeeList = employeeList;
}
}
DAO类使用静态列表来存储数据。这里我们需要实现实际的数据库交互。
EmployeeDAO.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com.howtodoinjava.rest.dao; import org.springframework.stereotype.Repository; import com.howtodoinjava.rest.model.Employee; import com.howtodoinjava.rest.model.Employees; @Repository public class EmployeeDAO { private static Employees list = new Employees(); static { list.getEmployeeList().add(new Employee(1, "Lokesh", "Gupta", "howtodoinjava@gmail.com")); list.getEmployeeList().add(new Employee(2, "Alex", "Kolenchiskey", "abc@gmail.com")); list.getEmployeeList().add(new Employee(3, "David", "Kameron", "titanic@gmail.com")); } public Employees getAllEmployees() { return list; } public void addEmployee(Employee employee) { list.getEmployeeList().add(employee); } } |
import org.springframework.stereotype.Repository;
import com.howtodoinjava.rest.model.Employee;
import com.howtodoinjava.rest.model.Employees;
@Repository
public class EmployeeDAO
{
private static Employees list = new Employees();
static
{
list.getEmployeeList().add(new Employee(1, "Lokesh", "Gupta", "howtodoinjava@gmail.com"));
list.getEmployeeList().add(new Employee(2, "Alex", "Kolenchiskey", "abc@gmail.com"));
list.getEmployeeList().add(new Employee(3, "David", "Kameron", "titanic@gmail.com"));
}
public Employees getAllEmployees()
{
return list;
}
public void addEmployee(Employee employee) {
list.getEmployeeList().add(employee);
}
}
5. Spring Boot REST演示
要启动应用程序,请main()
在SpringBootDemoApplication
类中运行该方法。它将启动嵌入式tomcat服务器。在服务器日志中,您将看到API已在spring上下文中注册。
Console
1 2 3 |
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/employees/],methods=[GET],produces=[application/json]}" onto public com.howtodoinjava.rest.model.Employees com.howtodoinjava.rest.controller. EmployeeController.getEmployees() s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/employees/],methods=[POST], consumes=[application/json], produces=[application/json]}" onto public org.springframework.http.ResponseEntity <java.lang.Object> com.howtodoinjava.rest.controller. EmployeeController.addEmployee( com.howtodoinjava.rest.model.Employee ) |
s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/employees/],methods=[POST], consumes=[application/json], produces=[application/json]}" onto public org.springframework.http.ResponseEntity <java.lang.Object> com.howtodoinjava.rest.controller. EmployeeController.addEmployee( com.howtodoinjava.rest.model.Employee )
5.1.HTTP GET /employees
服务器启动后,使用某个rest客户端访问API。

API响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{ "employeeList": [ { "id": 1, "firstName": "Lokesh", "lastName": "Gupta", "email": "howtodoinjava@gmail.com" }, { "id": 2, "firstName": "Alex", "lastName": "Kolenchiskey", "email": "abc@gmail.com" }, { "id": 3, "firstName": "David", "lastName": "Kameron", "email": "titanic@gmail.com" } ], } |
5.2.HTTP POST /employees

1 2 3 |
location: http://localhost:8080/employees/4 content-length: 0 date: Sat, 06 Oct 2018 04:33:37 GMT |
再次点击GET请求,这次我们也将获得添加的员工。
