当前位置:Java -> 使用Spring Boot编写OpenAPI 3文档
Java的采用已经从1.8版本转移到至少Java 17。与此同时,Spring Boot已经从2.x版本发展到3.2.2。springdoc项目已经从旧的库'springdoc-openapi-ui'转移到'springdoc-openapi-starter-webmvc-ui'来实现其功能。这些更新意味着依赖于旧文章的读者可能会发现自己在这些技术方面已经落后几年。作者更新了本文,确保读者使用最新版本,避免在迁移过程中出现过时信息的困扰。
这是三部分系列的第一部分。您可以在下面查看其他文章。
在本教程中,我们将尝试一个Spring Boot Open API 3启用的REST项目,并探索其一些功能。springdoc-openapi Java库已经迅速变得非常吸引人。
我们将参考构建RESTful Web服务和springdoc-openapi v2.5.0。
首先创建一个Maven JAR项目。以下是要使用的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>3.2.2</version>
<relativePath ></relativePath> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>sample</artifactId>
<version>0.0.1</version>
<name>sample</name>
<description>Demo project for Spring Boot with openapi 3 documentation</description>
<properties>
<java.version>17</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-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
注意"springdoc-openapi-starter-webmvc-ui
"依赖项。
现在,让我们创建一个小的Java bean类。
package sample;
import org.hibernate.validator.constraints.CreditCardNumber;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
public class Person {
private long id;
private String firstName;
@NotNull
@NotBlank
private String lastName;
@Pattern(regexp = ".+@.+\\..+", message = "Please provide a valid email address" )
private String email;
@Email()
private String email1;
@Min(18)
@Max(30)
private int age;
@CreditCardNumber
private String creditCardNumber;
public String getCreditCardNumber() {
return creditCardNumber;
}
public void setCreditCardNumber(String creditCardNumber) {
this.creditCardNumber = creditCardNumber;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getEmail1() {
return email1;
}
public void setEmail1(String email1) {
this.email1 = email1;
}
@Size(min = 2)
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
-
这是一个Java bean的示例。现在,让我们创建一个控制器。
package sample;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import jakarta.validation.Valid;
@RestController
public class PersonController {
@RequestMapping(path = "/person", method = RequestMethod.POST)
@io.swagger.v3.oas.annotations.parameters.RequestBody(required = true, content = @Content(examples = {
@ExampleObject(value = INVALID_REQUEST, name = "invalidRequest", description = "Invalid Request"),
@ExampleObject(value = VALID_REQUEST, name = "validRequest", description = "Valid Request") }))
public Person person(@Valid @RequestBody Person person) {
return person;
}
private static final String VALID_REQUEST = """
{
"id": 0,
"firstName": "string",
"lastName": "string",
"email": "abc@abc.com",
"email1": "abc@abc.com",
"age": 20,
"creditCardNumber": "4111111111111111"
}""";
private static final String INVALID_REQUEST = """
{
"id": 0,
"firstName": "string",
"lastName": "string",
"email": "abcabc.com",
"email1": "abcabc.com",
"age": 17,
"creditCardNumber": "411111111111111"
}""";
}
-
上面是一个样本REST控制器。
附注:通常我不喜欢在已经注释混乱的代码中添加额外的注释,但我认为这样的现成示例可能有用。迫使我这样做的另一个原因是,从Swagger UI生成的默认示例在使用@Pattern
时似乎产生了一些令人困惑的文本。这似乎是一个Spring UI的问题,而不是Springdoc的问题。
让我们在src\main\resources\application.properties中进行一些条目设置。
application-description=@project.description@
application-version=@project.version@
logging.level.org.springframework.boot.autoconfigure=ERROR
# server.error.include-binding-errors is now needed if we
# want to display the errors as shown in this article
# this can also be avoided in other ways as we will see
# in later articles
server.error.include-binding-errors=always
上面的条目将向OpenAPI文档传递与Maven构建相关的信息,并包括新的server.error.include-binding-errors
属性。
最后,让我们编写Spring Boot application
类:
package sample;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
@SpringBootApplication
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
@Bean
public OpenAPI customOpenAPI(@Value("${application-description}") String appDesciption,
@Value("${application-version}") String appVersion) {
return new OpenAPI()
.info(new Info()
.title("sample application API")
.version(appVersion)
.description(appDesciption)
.termsOfService("http://swagger.io/terms/")
.license(new License().name("Apache 2.0").url("http://springdoc.org")));
}
}
-
还要注意API版本和描述是如何从application.properties中利用的。
此时,该项目在Eclipse中的样子如下:
项目内容如上。接下来,从命令提示符或终端执行mvn clean package
。然后,执行java -jar target\sample-0.0.1.jar
。
也可以通过在IDE中运行SampleApplication.java
类来启动应用程序。
现在,访问Swagger UI — http://localhost:8080/swagger-ui.html。
点击绿色的Post按钮,并展开Person下的Schemas右侧的>符号。
让我们将最后的schemas部分展开一些:
契约之美在于它如何自动详细说明模型上的JSR-303注释。它可以直接覆盖许多重要的注释,并对其进行文档记录。然而,目前我没有看到它支持@javax.validation.constraints.Email
和@org.hibernate.validator.constraints.CreditCardNumber
在 "开箱即用" 的状态下。问题在于它们在生成的Swagger规范中没有文档记录,但这些约束是有效的。我们将在随后的文章中进一步讨论这个问题。
为了完整起见,让我们发布一个请求。点击尝试按钮。
点击蓝色的执行按钮。
让我们输入一个有效的输入,通过复制以下内容或者选择有效的输入下拉框。
{
"id": 0,
"firstName": "string",
"lastName": "string",
"email": "abc@abc.com",
"email1": "abc@abc.com",
"age": 20,
"creditCardNumber": "4111111111111111"
}
将这个有效的输入放入请求体部分。(我们还可以从下面的示例下拉框中选择"validRequest"。)
点击蓝色的执行按钮后,我们看到以下内容:
这只是对依赖项功能的简要介绍:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.5.0</version>
</dependency>
推荐阅读: 34.Redis并发竞争key问题应该如何解决?
本文链接: 使用Spring Boot编写OpenAPI 3文档