【译】构建 RESTful Web Service

原文地址:Building a RESTful Web Service

本指南属于入门指引系统,将指导您使用 Spring 创建 “Hello, World” RESTful 网络服务。

一、你将构建什么

您将在 http://localhost:8080/greeting 上创建一个接受 HTTP GET 请求的服务。
它将以问候语的 JSON 表示形式做出响应,如下表所示:

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

您可以在查询字符串中使用可选的名称参数自定义问候语,如下表所示:

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

如下表所示,name 参数值会覆盖 World 的默认值,并反映在响应中:

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

二、你必须做好以下准备

  • 大约 15 分钟
  • 最喜欢的文本编辑器或集成开发环境
  • Java 17 或更高版本
  • Gradle 7.5 以上版本或 Maven 3.5 以上版本
  • 您也可以直接将代码导入您的集成开发环境:
    • Spring Tool Suite (STS)
    • IntelliJ IDEA
    • VSCode

三、怎么完成这个指南

与大多数 Spring 入门指南一样,你可以从头开始并完成每个步骤,也可以绕过已经熟悉的基本设置步骤。无论哪种方式,你最终都能获得可运行的代码。
要从头开始,请继续阅读 “开始使用 Spring Initializr”。
要跳过基本步骤,请执行以下操作:

  • 下载并解压本指南的源代码库,或使用 Git 克隆:git clone https://github.com/spring-guides/gs-rest-service.git
  • cd 进入 gs-rest-service/initial\
  • 跳转到创建资源表示类。

完成后,你可以对照 gs-rest-service/complete 中的代码检查你的结果。

四、开始使用 Spring Initializr

你可以使用这个预初始化项目,然后点击生成下载 ZIP 文件。该项目已根据本教程中的示例进行了配置。
手动初始化项目:

  1. 导航至 https://start.spring.io。这项服务会拉入应用程序所需的所有依赖项,并为你完成大部分设置。
  2. 选择 Gradle 或 Maven 以及要使用的语言。本指南假定您选择的是 Java。
  3. 单击依赖项并选择 Spring Web。
  4. 单击生成。
  5. 下载生成的 ZIP 文件,这是一个根据你的选择进行配置的网络应用程序的归档文件。

如果您的集成开发环境集成了 Spring Initializr,您就可以在集成开发环境中完成此过程。

您也可以从 Github fork 该项目,然后在集成开发环境或其他编辑器中打开它。

五、创建资源表示类

在建立了项目和构建系统后,就可以创建网络服务了。
在创建过程中,首先要考虑服务的交互。
服务将处理对 /greetingGET 请求,可选择在查询字符串中加入 name 参数。GET 请求应返回 200 OK 响应,响应体中的 JSON 表示问候语。它应类似于以下输出:

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

id 字段是问候语的唯一标识符,content 是问候语的文本表示。
要为问候语表示建模,需要创建一个资源表示类。为此,为 id 和内容数据提供一个 Java 记录类,如下表所示(摘自 src/main/java/com/example/restservice/Greeting.java):

package com.example.restservice;

public record Greeting(long id, String content) { }

此应用程序使用 Jackson JSON 库将 Greeting 类型的实例自动转换为 JSON。网络启动器默认包含 Jackson。

六、创建资源控制器

在 Spring 构建 RESTful 网络服务的方法中,HTTP 请求由控制器处理。这些组件由 @RestController 注解标识,下面列表中的 GreetingController(来自 src/main/java/com/example/restservice/GreetingController.java)通过返回 Greeting 类的新实例来处理 /greetingGET 请求:

package com.example.restservice;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.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));
	}
}

该控制器简洁明了,但其内部却蕴含着丰富的功能。我们将一步步进行分解。
@GetMapping 注解确保对 /greetingHTTP GET 请求被映射到 greeting() 方法。

其他 HTTP Method 也有相应的注解(例如 POST 的 @PostMapping)。此外,还有一个 @RequestMapping 注解,所有 HTTP Method 的注解都源于该注解,并可作为同义词使用(例如 @RequestMapping(method=GET))。

@RequestParam 将查询字符串参数 name 的值绑定到 greeting() 方法的 name 参数中。如果请求中没有 name 参数,则使用 defaultValueWorld 默认值。
方法体的实现会根据计数器的下一个值创建并返回一个新的 Greeting 对象,该对象带有 idcontent 属性,并使用问候语模板格式化给定的名称。

传统 MVC 控制器与前面展示的 RESTful 网络服务控制器的主要区别在于创建 HTTP 响应体的方式。这种 RESTful 网络服务控制器不是依靠视图技术将问候语数据在服务器端呈现为 HTML,而是填充并返回一个问候语对象。对象数据将以 JSON 格式直接写入 HTTP 响应。

这段代码使用了 Spring @RestController 注解,它将类标记为控制器,其中每个方法都返回域对象,而不是视图。@RestController 是同时包含 @Controller@ResponseBody 的缩写。

包含问候语的域对象必须转换为 JSON 格式。得益于 Spring 的 HTTP 消息转换器支持,你无需手动进行转换。由于 Jackson 2 位于类路径上,Spring 的 MappingJackson2HttpMessageConverter 会自动选择将问候语实例转换为 JSON。

七、运行服务

Spring Initializr 会为你创建一个应用程序类。在这种情况下,你无需进一步修改该类。下面的列表(来自 src/main/java/com/example/restservice/RestServiceApplication.java)显示了应用程序类:

package com.example.restservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RestServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(RestServiceApplication.class, args);
	}

}

@SpringBootApplication 是一个很方便注解,可默认添加以下所有内容:

  • @Configuration: 将该类标记为应用程序上下文的 Bean 定义源。
  • @EnableAutoConfiguration: 告诉 Spring Boot 根据类路径设置、其他 Bean 和各种属性设置开始添加 Bean。例如,如果类路径上有 spring-webmvc,此注解就会将应用程序标记为 Web 应用程序,并激活关键行为,如设置 DispatcherServlet
  • @ComponentScan: 告诉 Spring 在 com/example 包中查找其他组件、配置和服务,从而找到控制器。

main() 方法使用 Spring Boot 的 SpringApplication.run() 方法启动应用程序。你注意到没有一行 XML 吗?也没有 web.xml 文件。该网络应用程序是 100% 纯 Java,您无需配置任何管道或基础设施。

构建可执行 JAR

您可以使用 Gradle 或 Maven 从命令行运行应用程序。您也可以构建一个可执行的 JAR 文件,其中包含所有必要的依赖关系、类和资源,然后运行该文件。创建一个可执行的 jar 文件可以方便地在整个开发生命周期内将服务作为应用程序在不同的环境中进行发送、版本控制和部署等操作。

如果使用 Gradle,可以使用 ./gradlew bootRun 运行应用程序。或者,也可以使用 ./gradlew build 来构建 JAR 文件,然后运行 JAR 文件,如下所示:

java -jar build/libs/gs-rest-service-0.1.0.jar

如果使用 Maven,可以使用 ./mvnw spring-boot:run 运行应用程序。或者,也可以使用 ./mvnw clean package 生成 JAR 文件,然后运行 JAR 文件,如下所示:

java -jar target/gs-rest-service-0.1.0.jar

这里描述的步骤将创建一个可运行的 JAR。您也可以创建一个经典的 WAR 文件。

服务应在几秒钟内启动并运行,然后显示日志输出。

八、测试服务

现在服务已经启动,请访问 http://localhost:8080/greeting,您应该可以看到

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

访问 http://localhost:8080/greeting?name=User,提供 name 查询字符串参数。注意 content 属性的值如何从 Hello, World! 变为 Hello, User!,如下所示:

{"id":2, "content": "Hello, User!"}

这一变化表明,GreetingController 中的 @RequestParam 按预期运行。name 参数的默认值为 World,但可以通过查询字符串显式重载。

还请注意 id 属性是如何从 1 变为 2 的。这证明您在多个请求中使用的是同一个 GreetingController 实例,而且其计数器字段在每次调用时都会按预期递增。

九、总结

恭喜您!您刚刚用 Spring 开发了一个 RESTful 网络服务。

你可能感兴趣的:(用户指南,Java编程,#,Spring,入门指南,Spring,Restful)