你将构建什么
你将在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分钟
- 一个最喜欢的编辑器或者集成环境
- JDK1.8以上
- Gradle 4+ 或者Maven 3.2+
- 你也可以直接把代码导入你的集成环境(Spring Tool Suite或IntelliJ IDEA)
如何完成本指南
与大多数Spring入门指南一样,您可以从头开始并完成每个步骤,也可以跳过您已经熟悉的基本设置步骤。无论采用哪种方式,最终都可以得到可以工作的代码。
要从头开始,请继续使用Spring Initialize。
要跳过这些基本步骤,请做以下步骤:
- 下载并解压本指南的源代码库,或者使用Git克隆它:git clone https://github.com/spring-guides/gs-rest-service.git
- cd到gs-rest-service/initial
- 跳过中间步骤创建一个资源表示类(Resource Representation Class)
完成后,可以根据gs-rest-service/complete中的代码检查结果。
从Spring Initialize开始
对于所有Spring应用程序,都应该从Spring Initializr开始。Initializr提供了一种快速的方法来拉入应用程序所需的所有依赖项,并为您完成了大量的设置工作。这个例子只需要Spring Web依赖项。从官方页面跳转过去的配置如下(不过,我选的java 8):
您可以直接从Spring Initializr获得包含必要依赖项的Maven构建文件。下面的清单显示了在采用Maven时创建的pom.xml文件:
<?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.4.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</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> <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>
采用Gradle的略。
创建一个资源表示类(Resource Representation Class)
现在已经设置了项目和构建系统,可以创建web服务了。
从考虑服务交互开始。
该服务将处理发送至/greeting的GET请求,查询字符串中可以有一个name参数。GET请求应该返回一个200 OK响应,其中包含表示一个问候语(greeting)的JSON。类似于下面:
{ "id": 1, "content": "Hello, World!" }
id字段是问候语的唯一标识符,content是问候语的文本表示。
为了对greeting这个资源的表示进行建模,创建一个资源表示类。为此,提供一个带有字段、构造器、访问器的POJO(plain old Java object),放在src/main/java/com/example/restservice/Greeting.java中:
package com.example.restservice; 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; } }
(该应用将采用默认包含的Jackson JSON库把Greeting实例转化成JSON)
创建资源控制器(Resource Controller)
在Spring构建的RESTful web服务中,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()方法。
@RequestParam将查询字符串参数name的值绑定到greeting()方法的name参数中。如果请求中没有name参数,则使用defaultValue,也就是World
传统MVC控制器和前面展示的RESTful web服务控制器之间的一个关键区别是HTTP响应体的创建方式。这个RESTful web服务控制器填充并返回一个greeting对象,而不是依赖视图技术来执行将greeting数据填充到HTML的服务器端渲染(server-side rendering)。对象数据将作为JSON直接写入HTTP响应。
这段代码使用Spring的@RestController注解,它将类标记为控制器,其中每个方法返回一个领域对象(domain object),而不是一个视图。@RestController是@Controller和@ResponseBody组合起来的简写。(PS. @ResponseBody的作用是将java对象转为json格式的数据插入到返回体中)
Greeting对象必须转换为JSON。由于Spring的HTTP消息转换器支持,您不需要手动进行此转换。因为Jackson2在类路径中,Spring的MappingJackson2HttpMessageConverter被自动选择来将Greeting实例转换为JSON。
@SpringBootApplication是一个方便的注解,它添加了以下所有内容:
- @Configuration:将类标记为应用程序上下文的bean定义源。
- @EnableAutoConfiguration:告诉Spring Boot开始添加基于类路径设置、其他bean和各种属性设置的bean。例如,如果spring-webmvc在类路径上,这个注释将把应用程序标记为web应用程序,并激活关键行为,如设置DispatcherServlet。
- @ComponentScan:告诉Spring在com/example包中寻找其他组件、配置和服务,让它找到控制器。
main()方法使用Spring Boot的SpringApplication.run()方法来启动应用程序。您是否注意到没有一行XML呢?也没有web.xml文件。这个web应用程序是100%纯Java的,您不需要配置任何管道或基础设施。
构建一个可执行JAR
maven的话,用下面的指令(在项目根目录):
mvn clean package
执行成功后,运行JAR:
java -jar target/gs-rest-service-0.1.0.jar
测试服务
访问http://localhost:8080/greeting?name=User返回如下内容
{"id":1,"content":"Hello, User!"}
刷新页面,id将递增。