本指南带你使用 Spring 创建一个“Hello, World” RESTful Web 服务。
将构建什么
服务接受对 http://localhost:8080/greeting 的 HTTP GET 请求,并以 JSON 表示返回问候语:
{"id":1,"content":"Hello, World!"}
可以通过查询字符串中可选的 name 参数自定义问候语:
http://localhost:8080/greeting?name=User
name 会覆盖默认值 World,并反映在响应中:
{"id":1,"content":"Hello, User!"}
所需条件
- 大约15分钟。
- 喜欢的文本编辑器或 IDE。
- 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 - 进入
gs-rest-service/initial。 - 从“创建资源表示类”继续。
完成后,可以对照 gs-rest-service/complete 中的代码检查结果。
使用 Spring Initializr
可以使用原文链接的预初始化项目,点击 Generate 下载 ZIP。项目已配置为适配本教程。
手动初始化:
- 打开 Spring Initializr。它会引入所需依赖,并完成大部分设置。
- 选择 Gradle 或 Maven,以及希望使用的语言。
- 在 Artifact 字段填写
rest-service。 - 点击 Dependencies,选择 Spring Web。
- 点击 Generate。
- 下载生成的 ZIP,其中包含按所选配置创建的 Web 应用。
如果 IDE 集成 Spring Initializr,也可以直接在 IDE 中完成。还可以在 GitHub 上 fork 项目,用 IDE 或其他编辑器打开。
创建资源表示类
项目和构建系统设置完成后,就可以创建 Web 服务。先考虑服务交互方式。
服务处理对 /greeting 的 GET 请求,可选接收查询字符串中的 name。响应应为 200 OK,正文包含问候语的 JSON,例如:
{
"id": 1,
"content": "Hello, World!"
}
id 是问候语的唯一标识符,content 是文字内容。
创建资源表示类,建模这两个字段。Java 使用 record,文件为 src/main/java/com/example/restservice/Greeting.java:
package com.example.restservice;
public record Greeting(long id, String content) { }
Kotlin 使用 data class,文件为 src/main/kotlin/com/example/restservice/Greeting.kt:
package com.example.restservice
data class Greeting(val id: Long, val content: String)
应用通过 Jackson JSON 库自动将 Greeting 实例转换为 JSON。Web starter 默认包含 Jackson。
创建资源控制器
在 Spring 的 RESTful Web 服务中,HTTP 请求由控制器处理。控制器由 @RestController 标识。下面的 GreetingController 处理 /greeting 的 GET 请求,并返回新的 Greeting 实例。
Java 文件为 src/main/java/com/example/restservice/GreetingController.java:
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(defaultValue = "World") String name) {
return new Greeting(counter.incrementAndGet(), template.formatted(name));
}
}
Kotlin 文件为 src/main/kotlin/com/example/restservice/GreetingController.kt:
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
private const val template = "Hello, %s!"
@RestController
class GreetingController {
private val counter = AtomicLong()
@GetMapping("/greeting")
fun greeting(@RequestParam name: String = "World") =
Greeting(counter.incrementAndGet(), template.format(name))
}
控制器很简洁,但底层完成了许多工作:
@GetMapping保证对/greeting的 HTTP GET 请求映射到greeting()。其他 HTTP 方法有对应注解,如 POST 使用@PostMapping。它们都派生自@RequestMapping,后者也可作为同义形式,例如@RequestMapping(method=GET)。@RequestParam将查询参数name绑定到方法的name参数。请求缺少参数时,使用默认值World。- 方法使用计数器的下一个值作为
id,用问候模板格式化传入的名称作为content,创建并返回Greeting。
传统 MVC 控制器与这个 RESTful 服务控制器的关键差别,在于响应正文的生成方式。这个控制器不依赖视图技术在服务器端把问候数据渲染为 HTML,而是填充并返回 Greeting 对象,再直接写入 JSON 响应。
@RestController 表示类中的方法返回领域对象而非视图,它是同时使用 @Controller 和 @ResponseBody 的简写。
Greeting 必须转换为 JSON。Spring 的 HTTP 消息转换器使你无需手工转换。由于 Jackson 位于类路径,Spring 自动选择 JacksonJsonHttpMessageConverter 转换实例。
运行服务
Spring Initializr 会创建应用类,本例无需进一步修改。
Java 文件为 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);
}
}
Kotlin 文件为 src/main/kotlin/com/example/restservice/RestServiceApplication.kt:
package com.example.restservice
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
class RestServiceApplication
fun main(args: Array<String>) {
runApplication<RestServiceApplication>(*args)
}
@SpringBootApplication 是便捷注解,包含以下功能:
@Configuration:将类标记为应用上下文的 bean 定义来源。@EnableAutoConfiguration:根据类路径、其他 bean 和属性设置添加 bean。例如,存在spring-webmvc时,把应用识别为 Web 应用并配置DispatcherServlet等核心行为。@ComponentScan:查找com/example包中的组件、配置和服务,从而发现控制器。
main() 用 SpringApplication.run() 启动应用。没有任何 XML,也没有 web.xml;这个 Web 应用完全使用 Java,不必手动配置底层设施。
构建可执行 JAR
可从命令行通过 Gradle 或 Maven 运行,也可构建包含全部依赖、类和资源的可执行 JAR。单个可执行 JAR 便于在开发生命周期中跨环境分发、版本管理和部署。
Gradle 运行:./gradlew bootRun。也可用 ./gradlew build 构建,然后:
java -jar build/libs/gs-rest-service-0.0.1-SNAPSHOT.jar
Maven 运行:./mvnw spring-boot:run。也可用 ./mvnw clean package 构建,然后:
java -jar target/gs-rest-service-0.0.1-SNAPSHOT.jar
会显示日志输出,服务应在数秒内启动。
测试服务
启动后访问 http://localhost:8080/greeting,应看到:
{"id":1,"content":"Hello, World!"}
访问 http://localhost:8080/greeting?name=User,传入查询参数后,content 从 Hello, World! 变为 Hello, User!:
{"id":2,"content":"Hello, User!"}
这展示了 GreetingController 中 @RequestParam 的工作方式:默认名称为 World,也可由查询参数覆盖。
id 从1变为2,表明多个请求由同一个 GreetingController 实例处理,其 counter 按预期在每次调用时递增。
完成与延伸阅读
你已经使用 Spring 创建了 RESTful Web 服务。原文还列出这些相关指南:通过 REST 访问 GemFire、MongoDB、JPA、Neo4j 数据;使用 MySQL 访问数据;消费 RESTful 服务及其 AngularJS、jQuery、rest.js 示例;保护 Web 应用;构建 REST 服务;React.js 与 Spring Data REST;Spring Boot 应用;Restdocs API 文档;跨域请求;超媒体驱动的 REST 服务;Circuit Breaker。各指南链接请从原文“See Also”进入。
如想撰写新指南或参与已有指南,请参阅原文贡献指南。
原文:Building a RESTful Web Service;作者/来源:Spring Guides。本文为中文译稿,代码与示例输出保留原文,未在本环境运行 Java、Kotlin 或构建命令。
原文明确:代码采用 ASLv2(Apache License 2.0);文字采用 Attribution, NoDerivatives Creative Commons 许可。NoDerivatives 不自动授予公开分享译文的权利;本任务中用户已明确授权本批汉化转载,该额外授权的权利人来源与范围需在实际发布前核验。
Spring、Java、Windows、Microsoft Azure、AWS、Amazon Web Services 等商标归各自权利人所有。











暂无评论内容