原文地址: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!"}
与大多数 Spring 入门指南一样,你可以从头开始并完成每个步骤,也可以绕过已经熟悉的基本设置步骤。无论哪种方式,你最终都能获得可运行的代码。
要从头开始,请继续阅读 “开始使用 Spring Initializr”。
要跳过基本步骤,请执行以下操作:
git clone https://github.com/spring-guides/gs-rest-service.git
gs-rest-service/initial
\完成后,你可以对照 gs-rest-service/complete
中的代码检查你的结果。
你可以使用这个预初始化项目,然后点击生成下载 ZIP 文件。该项目已根据本教程中的示例进行了配置。
手动初始化项目:
如果您的集成开发环境集成了 Spring Initializr,您就可以在集成开发环境中完成此过程。
您也可以从 Github fork 该项目,然后在集成开发环境或其他编辑器中打开它。
在建立了项目和构建系统后,就可以创建网络服务了。
在创建过程中,首先要考虑服务的交互。
服务将处理对 /greeting
的 GET
请求,可选择在查询字符串中加入 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
类的新实例来处理 /greeting
的 GET
请求:
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
注解确保对 /greeting
的 HTTP GET
请求被映射到 greeting()
方法。
其他 HTTP Method 也有相应的注解(例如 POST 的
@PostMapping
)。此外,还有一个@RequestMapping
注解,所有 HTTP Method 的注解都源于该注解,并可作为同义词使用(例如@RequestMapping(method=GET)
)。
@RequestParam
将查询字符串参数 name
的值绑定到 greeting()
方法的 name
参数中。如果请求中没有 name
参数,则使用 defaultValue
的 World
默认值。
方法体的实现会根据计数器的下一个值创建并返回一个新的 Greeting
对象,该对象带有 id
和 content
属性,并使用问候语模板格式化给定的名称。
传统 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,您无需配置任何管道或基础设施。
您可以使用 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 网络服务。