了解如何使用 Spring 创建 RESTful web 服务。

RESTful 架构,目前最流行的一种互联网软件架构,基于 HTTP,可以使用 XML 格式定义或 JSON 格式定义。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。


0. 前言

你将创建什么?

你将创建一个拥有问候(greeting)接口的 Web 服务。它将会以 JSON 格式进行响应:

{"id":1,"content":"Hello, World!"}

你还可以对接口传入可选参数 name

http://localhost:8080/greeting?name=lxiaocode

name 参数将会覆盖默认值,并进行响应:

{"id":1,"content":"Hello, lxiaocode!"}

你需要什么知识?

  • 一款你熟悉的 IDE(如,IntelliJ IDEA)
  • Java 1.8 或更高的版本
  • Maven 3.2 或更高的版本

1. 创建初始项目

1.1 创建 Spring Initializr 项目

你可以使用 IntelliJ IDEA 进行创建项目,也可以在 Spring Initializr 进行创建。

1.2 导入 maven 依赖

在默认的 Spring Boot 项目的 pom.xml 文件包含 spring-boot-starter (核心模块)。创建 Web 项目需要引入 Spring-boot-starter-web (Web模块),因为 Web 模块已经包含了核心模块,所以引入 Web 模块后可以删除原有的核心模块:

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.lxiaocode</groupId>
<artifactId>rest-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>rest-service</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
</properties>

<!-- 以下管理你的 maven 依赖 -->
<dependencies>
<!-- 导入 web 服务依赖 -->
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<!-- 以上管理你的 maven 依赖 -->

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

2. 创建资源表示类

你现在已经完成对项目的初始设置,可以开始创建你的 Web 服务了。该服务会处理 /greeting 的 HTTP GET 请求,并且会返回 JSON 格式的响应体。如:

{
"id": 1,
"content": "Hello, World!"
}

id 字段表示问候的唯一标识符,content 字段表示问候的文本信息。

为了模拟问候,需要创建一个与之对应的 Java 对象。只需要提供 idcontent 字段及其存取方法即可:

public class Greeting {

private final long id;
private final String content;

public Greeting(long id, String content) {
this.id = id;
this.content = content;
}

public long getId() {
return id;
}

public String getContent() {
return content;
}
}

为什么使用 JSON 格式进行响应时,需要创建 Java 类?

在这个程序中,我们将使用 Jackson 的 JSON 库,它可以自动的将 Java 对象实例转换为 JSON 格式。在默认的情况下,web starter 已经包含了 Jackson JSON 库,我们可以直接使用。

3. 创建资源控制器

使用 Spring 创建 RESTful Web 服务,需要一个控制器处理 HTTP 请求。创建 GreetingController 类并使用 @RestController 注解将其标识为控制器:

@RestController
public class GreetingController {

private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();

@GetMapping("/greeting")
public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
}

这是一个十分简单的控制器,我们将一步步对其进行解释。

@RestController 注解将该类标记为控制器,并且其中的方法返回的是一个域对象而不是视图。

@RestController 中的 “Rest” 是什么意思?

其实 @RestController 组件是 @Controller@ResponseBody 的组合。

  • @Controller 将类标记为控制器。
  • @ResponseBody 表示控制器中的方法返回的是域对象。

@GetMapping 注解确保 HTTP GET 请求 /greeting 接口时映射到 greeting() 方法。

如果需要映射 HTTP POST 请求需要什么注解?

其他的 HTTP 请求类型也有对应的注解(如,@PostMapping)。还有 @RequestMapping 也可以表示 HTTP 请求(如,@RequestMapping(method=GET))。

@RequestParam 注解将 greeting() 方法中的 name 参数的值绑定到一起,如果请求时没有 name 将使用默认值 “World”。

在方法体中,创建并返回了一个新的 Greeting 实例。其中 id 字段使用计数器进行自增,content 字段使用模板进行格式化。

4. Spring Boot 启动类

你会发现,项目中还有一个标记 @SpringBootApplication 注解的类,这就是 Web 服务的启动类。

@SpringBootApplication 注解包含了以下内容:

  • @Configuration 表示了该类是应用程序上下文的 bean 定义类。
  • @EnableAutoConfiguration 告诉 Spring Boot 开始加载 bean。
  • @ComponentScan 告诉 Spring Boot 扫描其他组件。

main() 方法中,使用了 Spring Boot 的 SpringApplication.run() 方法,用于启动程序。

5. 测试 Web 服务

现在启动 Web 服务,并访问 http://localhost:8080/greeting

# 看到 8080 端口已启动,说明项目已经启动完成了
... Tomcat started on port(s): 8080 (http) with context path ''
// 访问 http://localhost/greeting 将看到此响应
{"id":1,"content":"Hello, World!"}

// 再次访问 http://localhost/greeting?name=lxiaocode 将看到此响应
// 注意 id 已经变成了 2
{"id":2,"content":"Hello, lxiaocode!"}

GitHub 项目源码


参考文献:Spring | Guides

评论