Springboot教程:Springboot 2 REST API示例

本篇将学习使用Spring boot 2框架创建REST API,该框架将JSON响应返回给客户端。在这个Spring Boot 2 REST API教程中,我们将逐步创建两个简单的GET和POST API并对其进行测试。

1. Maven依赖

首先,创建一个简单的maven Web项目并更新pom.xml文件中的spring boot依赖项。

重要的依赖关系是spring-boot-starter-parentspring-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方法。可以 根据需要添加更多方法。

  1. HTTP GET / employees - 返回employees列表。
  2. 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来应用。

在这种情况下,它会做一些事情。

  1. 它检测spring-webmvc,因此配置默认的spring mvc应用程序bean。它有助于扫描和配置@RestController以及类似的注释。
  2. 它检测嵌入式tomcat jar,为我们配置嵌入式tomcat。
  3. 它检测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。

Spring Boot REST HTTP GET
Spring Boot REST HTTP GET

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

Spring Boot REST HTTP POST
Spring Boot REST HTTP POST
响应标头
1
2
3
location: http://localhost:8080/employees/4
content-length: 0
date: Sat, 06 Oct 2018 04:33:37 GMT

再次点击GET请求,这次我们也将获得添加的员工。

Spring Boot REST HTTP GET - 更新

发表评论

登录后才能评论
关注我们