使用 Spring Doc 为 Spring REST API 生成 OpenAPI 3.0 文档

Spring Boot 3 整合 springdoc-openapi

概述

springdoc-openapi 是一个用于自动生成 OpenAPI 3.0 文档的库,它支持与 Spring Boot 无缝集成。通过这个库,你可以轻松地生成和展示 RESTful API 的文档,并且可以使用 Swagger UI 或 ReDoc 进行交互式测试。

环境准备

  • Spring Boot 3.x
  • Java 17+
  • Maven

创建 Spring Boot 项目

首先,创建一个新的 Spring Boot 项目。你可以使用 Spring Initializr 来快速生成项目结构。

添加依赖

pom.xml 文件中添加 springdoc-openapi-ui 依赖:

<dependencies>
    <!-- Spring Web 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

   <!-- springdoc-openapi-starter-webmvc-ui 是一个 Spring Boot Starter,它包含了 springdoc-openapi-ui 及其他必要的依赖,简化了依赖管理和配置 -->
		<dependency>
			<groupId>org.springdoc</groupId>
			<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
			<version>2.6.0</version>
		</dependency>
    <!-- springdoc-openapi-ui 依赖 -->
<!--	<dependency>-->
<!--       <groupId>org.springdoc</groupId>-->
<!--       <artifactId>springdoc-openapi-ui</artifactId>-->
<!--       <version>1.8.0</version>-->
<!--    </dependency>-->
</dependencies>

配置文件

application.ymlapplication.properties 中配置 Swagger UI 和 ReDoc 的路径(可选):

springdoc:
  api-docs:
    path: /v3/api-docs
  swagger-ui:
    path: /swagger-ui.html
    enabled: true
    operationsSorter: method
  show-actuator: true

或者在 application.properties 中:

springdoc.api-docs.path=/v3/api-docs
springdoc.swagger-ui.path=/swagger-ui.html
springdoc.swagger-ui.enabled=true
springdoc.swagger-ui.operations-sorter=method
springdoc.show-actuator=true

创建模型类

创建一个简单的模型类 User,并使用 @Schema 注解来描述字段:

package org.springdoc.demo.services.user.model;

import io.swagger.v3.oas.annotations.media.Schema;

@Schema(name = "User", description = "用户实体")
public class User {
  @Schema(description = "用户ID", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
  private Long id;

  @Schema(description = "用户名", example = "john_doe", requiredMode = Schema.RequiredMode.REQUIRED)
  private String username;

  @Schema(description = "电子邮件", example = "john.doe@example.com", requiredMode = Schema.RequiredMode.REQUIRED)
  private String email;

  public User(Long id, String username, String email) {
    this.id = id;
    this.username = username;
    this.email = email;
  }

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }
}

如何想隐藏模型的某个字段,不生成文档,可以使用@Schema(hidden = true)。
当我们的 model 包含 JSR-303 Bean 验证注解(如 @NotNull、@NotBlank、@Size、@Min 和 @Max)时,springdoc-openapi 库会使用它们为相应的约束生成额外的 schema 文档。

/*
 *
 *  * Copyright 2019-2020 the original author or authors.
 *  *
 *  * Licensed under the Apache License, Version 2.0 (the "License");
 *  * you may not use this file except in compliance with the License.
 *  * You may obtain a copy of the License at
 *  *
 *  *      https://www.apache.org/licenses/LICENSE-2.0
 *  *
 *  * Unless required by applicable law or agreed to in writing, software
 *  * distributed under the License is distributed on an "AS IS" BASIS,
 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  * See the License for the specific language governing permissions and
 *  * limitations under the License.
 *
 */

package org.springdoc.demo.services.book.model;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

/**
 * The type Book.
 */
public class Book {

	/**
	 * The Id.
	 */
	@Schema(hidden = true)
	private long id;

	/**
	 * The Title.
	 */
	@NotBlank
	@Size(min = 0, max = 20)
	private String title;

	/**
	 * The Author.
	 */
	@NotBlank
	@Size(min = 0, max = 30)
	private String author;
}

创建 RESTful 控制器

创建一个控制器 UserController,包含两个方法:一个使用 OpenAPI 注解,另一个不使用。
我们使用 @Operation 和 @ApiResponses 对 controller 的 /api/user/{id} 端点进行注解。 其实不使用
@Operation 和 @ApiResponses,也会生成文档,只是信息少一些。

package org.springdoc.demo.services.user.controller;

import org.springdoc.demo.services.user.model.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/user")
public class UserController {

  private final Map<Long, User> userMap = new HashMap<>();

  public UserController() {
    // 初始化一些示例数据
    userMap.put(1L, new User(1L, "john_doe", "john.doe@example.com"));
    userMap.put(2L, new User(2L, "jane_doe", "jane.doe@example.com"));
  }

  @Operation(
      summary = "获取用户信息",
      description = "根据用户ID获取用户信息",
      responses = {
          @ApiResponse(
              responseCode = "200",
              description = "成功",
              content = @Content(
                  mediaType = "application/json",
                  schema = @Schema(implementation = User.class)
              )
          ),
          @ApiResponse(
              responseCode = "404",
              description = "未找到用户"
          )
      }
  )
  @GetMapping("/{id}")
  public ResponseEntity<User> getUserById(@PathVariable @Parameter(description = "用户ID") Long id) {
    User user = userMap.get(id);
    if (user != null) {
      return ResponseEntity.ok(user);
    } else {
      return ResponseEntity.notFound().build();
    }
  }

  @GetMapping("/{id}/no-annotations")
  public ResponseEntity<User> getUserByIdNoAnnotations(@PathVariable Long id) {
    User user = userMap.get(id);
    if (user != null) {
      return ResponseEntity.ok(user);
    } else {
      return ResponseEntity.notFound().build();
    }
  }
}

自定义全局配置

如果你需要自定义全局的 OpenAPI 文档信息,可以创建一个配置类 OpenApiConfig

package com.example.demo.config;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OpenApiConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
            .info(new Info()
                .title("示例 API 文档")
                .version("1.0")
                .description("这是一个示例 API 文档,用于演示如何整合 springdoc-openapi。")
                .contact(new Contact()
                    .name("你的名字")
                    .email("your.email@example.com")
                    .url("https://example.com"))
                .license(new License()
                    .name("Apache 2.0")
                    .url("http://www.apache.org/licenses/LICENSE-2.0")));
    }
}

启动应用

创建一个 Spring Boot 应用程序的主类:

package com.example.demo;

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

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

访问 Swagger UI

启动应用程序后,你可以通过以下 URL 访问 Swagger UI:

http://localhost:8080/swagger-ui.html

在 Swagger UI 页面中,你可以看到生成的 API 文档,并且可以进行交互式测试。

配置分组

可以在通过配置 application.yml 来设置分组

springdoc:
  api-docs:
    version: openapi_3_1
    path: /v3/api-docs
  version: '@springdoc.version@'
  swagger-ui:
    path: /swagger-ui.html
    enabled: true
    operationsSorter: method
    use-root-path: true
  #包扫描路径
#  packages-to-scan: com.ruoyi.tenant.controller
  group-configs:
    - group: user
      #按包路径匹配
      packagesToScan: org.springdoc.demo.services.user
    - group: book
      #按路径匹配
      pathsToMatch: /api/book/**
      #按包路径匹配
      packagesToScan: org.springdoc.demo.services.book

也可以在配置类里配置

package org.springdoc.demo.services.config;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OpenApiConfig {

  @Bean
  public OpenAPI customOpenAPI() {
    return new OpenAPI()
        .info(new Info()
            .title("示例 API 文档")
            .version("1.0")
            .description("这是一个示例 API 文档,用于演示如何整合 springdoc-openapi。")
            .contact(new Contact()
                .name("你的名字")
                .email("your.email@example.com")
                .url("https://example.com"))
            .license(new License()
                .name("Apache 2.0")
                .url("http://www.apache.org/licenses/LICENSE-2.0")));
  }

  @Bean
  public GroupedOpenApi userApi() {
    return GroupedOpenApi.builder()
        .group("user")
//        .packagesToScan("org.springdoc.demo.services.user")
        .pathsToMatch("/api/user/**")
        .build();
  }

  @Bean
  public GroupedOpenApi bookpi() {
    return GroupedOpenApi.builder()
        .group("book")
        .pathsToMatch("/api/book/**")
//        .packagesToScan("org.springdoc.demo.services.book")
        .build();
  }

}

两个方法选择一个就可以了。

总结

通过以上步骤,你已经成功地在 Spring Boot 3 项目中集成了 springdoc-openapi,并生成了 OpenAPI 3.0 文档。你可以根据需要进一步扩展和定制文档,以满足项目的具体需求。
推荐使用 springdoc-openapi 的理由如下:

  • springdoc-openapi 是 spring 官方出品,与 springboot 兼容更好(springfox 兼容有坑)
  • springdoc-openapi 社区更活跃,springfox 已经 2 年没更新了 springdoc-o
  • penapi 的注解更接近 OpenAPI 3 规范

代码仓库:https://github.com/kuankuanba/springdoc-demo.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/905103.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

8、Node.js Express框架

五、Express框架 5.1概念 Express框架是一个基于Node.js平台的极简、灵活的WEB开发框架:www.express.com.cn 简单来说,Express是一个封装好的工具包,封装了很多功能,便于我们开发WEB应用 5.2安装 npm i express5.3 Express初体验 //01-express初体验.js //1.导入exrp…

Python(包和模块)

包 定义 包是将模块以文件夹的组织形式进行分组管理的方法&#xff0c;以便更好地组织和管理相关模块。 包是一个包含一个特殊的__init__.py文件的目录&#xff0c;这个文件可以为空&#xff0c;但必须存在&#xff0c;以标识目录为Python包。 包可以包含子包&#xff08;子…

万方数据库功能亮点介绍及个人下载万方论文的方法

一、万方数据库介绍 万方数据知识服务平台是北京万方数据股份有限公司主要产品之一。该平台整合数亿条全球优质学术资源&#xff0c;集成期刊、学位、会议、标准、专利等十余种资源类型、品质知识资源、先进的发现技术、人性化设计于一身&#xff0c;是国内一流的品质知识资源…

18 实战:基于Tkinter和OpenCV的视频编码器:实现MPEG4矩形帧编码器

引言 在视频处理领域,视频编码器的设计与实现一直是研究的热点。本文将深入解析一段基于Python的代码,该代码利用Tkinter、OpenCV和NumPy库构建了一个MPEG4矩形帧编码器的图形用户界面(GUI)。通过详尽的代码讲解,帮助读者全面理解视频编码的基本原理及其在实际应用中的实…

12-Docker发布微服务

12-Docker发布微服务 Docker发布微服务 搭建SpringBoot项目 新建一个SpringBoot项目 选择依赖项Spring Web和Spring Boot Actuator 在com.qi.docker_boot下创建controller目录&#xff0c;并在该目录下创建OrderController的java类 OrderControllerjava类的内容如下&#xf…

【IEEE出版|:IEEE Xplore,EI Compendex,Scopus检索|征稿正在进行中!】

第七届机械工程与智能制造国际会议&#xff08;WCMEIM 2024&#xff09; 2024 7th World Conference on Mechanical Engineering and Intelligent Manufacturing 【会议信息】 会议日期&#xff1a;2024年11月15-17日 会议地点&#xff1a;中国武汉&#xff08;武汉纺织大学…

如何成为开源代码库Dify的contributor:解决issue并提交PR

前言 Dify 是一个开源的大语言模型&#xff08;LLM&#xff09;应用开发平台&#xff0c;它融合了后端即服务&#xff08;Backend as Service&#xff09;和LLMOps的理念&#xff0c;旨在简化和加速生成式AI应用的创建和部署。Dify提供了一个用户友好的界面和一系列强大的工具…

前端如何安全存储密钥,防止信息泄露

场景 把公钥硬编码在前端代码文件里&#xff0c;被公司安全检测到了要整改&#xff0c;于是整理几种常见的前端密钥存储方案。 1. 设置环境变量再读取 在打包或部署前端应用时&#xff0c;可以将密钥配置为环境变量&#xff0c;在应用运行时通过环境变量读取密钥。这样可以将密…

深入了解 Three.js 中的材质与光照

开发领域&#xff1a;前端开发 | AI 应用 | Web3D | 元宇宙 技术栈&#xff1a;JavaScript、React、ThreeJs、WebGL、Go 经验经验&#xff1a;6年 前端开发经验&#xff0c;专注于图形渲染和AI技术 开源项目&#xff1a;github 晓智元宇宙、数字孪生引擎、前端面试题 大家好&am…

【Linux】网络基础常识{OSI七层模型 TCPIP 端口号 各种协议}_哪种nat类型适用于多个内部设备共享有限的公共ip地址

文章目录 1.网络常识 1.0DHCP协议1. 1IP地址/MAC地址/ARP协议是什么&#xff1f; IP/MACARP&#xff1a;IP ⇒ MAC 1.2手机连接wifi的原理 SSID与BSSID 手机连接wifiSSID与BSSID 1.3手机如何通过“数据/流量”上网&#xff1f;1.4电脑连接wifi的原理&#xff1f;电脑通过热点…

uniapp使用uni-push模拟推送

uniapp使用uni-push模拟推送 第一步先去uniapp开发者中心添加开通uni-push功能 这里的Android 应用签名可以先用测试的官网有,可以先用这个测试 官方测试链接文档地址 在项目中的配置文件勾选 组件中使用 如果要实时可以去做全局ws //消息推送模版uni.createPushMessage(…

ai画质修复工具有哪些?这4款AI照片修复神器建议收藏!

在当今这个科技迅猛发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度重塑我们的日常生活&#xff0c;而照片修复领域正是AI技术大放异彩的舞台。从年代久远、泛黄的老照片到追求极致细节的现代摄影佳作&#xff0c;AI以其非凡的能力&#xff0c;成…

MES管理系统在工艺管理中具备哪些作用

在现代制造业的洪流中&#xff0c;MES管理系统正逐步成为工艺管理领域的一股强大力量&#xff0c;它不仅革新了传统的管理方式&#xff0c;还为企业带来了前所未有的效率提升与成本控制优势。尽管许多企业尚未全面拥抱这一数字化变革&#xff0c;但MES管理系统在工艺管理中的潜…

IM_自定义audio播放消息

做即时通讯&#xff0c;除了文字、图片、表情、还有媒体消息&#xff0c;整理一下制作过程中自定义聊天框中的audio 效果图 tsx完整代码 AzEventBus 是解决点击多个语音播放时候&#xff0c;保证只有一个在播放;没什么特别的&#xff0c;就是自己简单封装了个EvenBusAzEventBus…

tcp shutdown, fin_wait1, fin_wait2, close_wait, last_ack, 谢特!

TCP 作为双向传输协议&#xff0c;如果你想只收不发&#xff0c;可以单向关掉发&#xff0c;shutdown(socket.SHUT_WR)&#xff0c;但不建议这么做。 看以下代码&#xff1a; #!/Users/zhaoya/myenv/bin/python3 # client import socketclient_socket socket.socket(socket.…

怎么知道社媒上用户在讨论品牌什么?评价如何?

现在社交媒体不再仅是人们闲聊和分享生活片段的地方&#xff0c;更是品牌了解市场趋势和消费者需求的重要渠道。所以做号社媒上用户声音的聆听&#xff0c;企业更能抓住客户需求、抢占潜力市场&#xff0c;进一步占据更多市场份额&#xff0c;获得精准客户。 做好用户声音聆听…

【QT】Qt窗口(上)

个人主页~ Qt窗口 一、菜单栏二、工具栏三、状态栏四、浮动窗口五、对话框1、简介&#xff08;1&#xff09;模态对话框&#xff08;2&#xff09;非模态对话框&#xff08;3&#xff09;混合属性对话框 Qt窗口是通过QMainWindow类来实现的&#xff0c;我们之前的学习是通过QWi…

第二十章 Vue组件通信之父子通信

目录 一、引言 二、组件关系分类 三、组件通信的解决方案 3.1. 父子通信流程图 3.2. 父组件通过 props 将数据传递给子组件 3.2.1. 代码App.vue 3.2.2. 代码MySon.vue 3.3. 子组件利用 $emit 通知父组件修改更新 ​编辑3.3.1. 代码App.vue 3.3.2. 代码MySon.vue 3…

用ChatGPT提升工作效率:从理论到实际应用

伴人工智能技术的迅速演进&#xff0c;像ChatGPT这类语言模型已成为提升工作效率的关键工具。这类模型不仅具备处理海量数据的能力&#xff0c;还能自动化许多日常任务&#xff0c;从而提高决策的准确性。本文将深入探讨如何在工作中利用ChatGPT等AI工具提升效率&#xff0c;涵…

golang 服务注册与服务发现框架 入门与实践

Go语言中服务注册与发现的应用 在Go微服务架构中&#xff0c;服务注册与服务发现是实现服务间通信和解耦的关键。随着服务数量的增长&#xff0c;手动管理服务之间的依赖关系变得异常复杂且容易出错。因此&#xff0c;自动化服务注册与发现机制变得尤为重要。当一个Go微服务启…