SpringBoot 3.0+ 整合 Swagger 3.0

SpringBoot 3 整合 Swagger 3.0

理解概念

  1. SpringFox 与 Swagger 的关系: Springfox 是一套可以帮助 Java 开发者自动生成 API 文档的工具,它是基于 Swagger 2.x 基础上开发的。 随着时间的推移,Swagger2.x 成为历史,springfox-boot-starter 的坐标从 3.0.0 版本(2020 年 7 月 14 日)开始没有持续更新;
  1. SpringDoc 对应坐标是 springdoc-openapi-ui,它是一个集成 Swagger UI 和 ReDoc 的接口文档生成工具,在使用上与 springfox-boot-starter 类似,但提供了更为灵活、功能更加强大的工具。其中除了可以生成Swagger UI 风格的接口文档,还提供了 ReDoc 的文档渲染方式,可以自动注入 OpenAPI 规范的 JSON 描述文件,支持OAuth2、JWT 等认证机制,并且支持全新的 OpenAPI 3.0 规范

因而使用的是SrpingDoc整合SpringBoot 3

SpringBoot用的版本是3.2.2

xml 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.2</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

springdoc-openapi-starter-webmvc-ui用的版本是2.6.0

xml 复制代码
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.6.0</version>
</dependency>
  1. 在项目启动类上加上注解扫描
  1. 在项目的properties或者是yaml文件中进行对swagger的配置,我这里用的是yaml
yaml 复制代码
spring
  application:
  name: home-swagger

springdoc:
  api-docs:
    enabled: true  # 开启OpenApi接口
    path: /v3/api-docs  # 自定义路径,默认为 "/v3/api-docs"
  swagger-ui:
    enabled: true  #开启swagger界面,依赖OpenApi,需要OpenApi同时开启
    path: /swagger-ui.html # 自定义路径,默认为"/swagger-ui/index.html"
    # Packages to include,多个用 , 分割
    packagesToScan: com.home.api.controller
    token: iolkiolk
  1. 在controller类上加上@Tag注解说明
less 复制代码
@Tag(name = "ApplicationController", description = "Application Controller"
        , externalDocs = @ExternalDocumentation(description = "这是一个接口文档介绍"))

在controller中的方法上添加注解说明,有很多参数可以配置,例如在一个post方法上:

less 复制代码
@Operation(
        summary = "查询全部学生数据",
        description = "查询学生信息,并返回响应结果信息"
)
@PostMapping("/getAll")
public PageInfo<HomeVo> getAllHomes(@RequestBody HomeRequest homeRequest){}
  1. 增加Swagger的配置类,注意导入的info包是io.swagger.v3.oas.models.info.Info
typescript 复制代码
import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
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 Swagger3Config {

    @Bean
    public OpenAPI springShopOpenAPI() {
        return new OpenAPI()
                .info(new Info().title("Home API")
                        .description("Swagger3 Spring Boot 3.0 application")
                        .version("v0.0.1")
                        .license(new License().name("Apache 2.0").url("http://springdoc.org")))
                .externalDocs(new ExternalDocumentation()
                        .description("home-ui")
                        .url("https://home-ui.com"));

    }
}

5.启动项目,输入localhost:8081/swagger-ui.html查看项目扫描后的接口文档

看到swagger整理的项目接口文档后,前端同事即可查看每个接口的请求路径,方法,入参和出参,进行接口联调。 更多的是大家要相约一种约定,规范。swagger还有许多注解,满足开发者的需要,更多的内容请查阅网上资料。

swagger3 访问权限控制,生产环境屏蔽

在这里,想分享的是实用场景,对swagger3文档链接,进行访问权限控制,加强对项目文档的安全性,一般的对swagger-ui.html这样的url,缺少基本的安全控制,在这里我们可以使用过滤器,检查url有没有携带指定的参数,进一步进行对其校验

1.首先在前面的yaml中可以看到有一个springdoc.swagger-ui.token的配置:

yaml 复制代码
springdoc:
  api-docs:
    enabled: true  # 开启OpenApi接口
    path: /v3/api-docs  # 自定义路径,默认为 "/v3/api-docs"
  swagger-ui:
    enabled: true  #开启swagger界面,依赖OpenApi,需要OpenApi同时开启
    path: /swagger-ui.html # 自定义路径,默认为"/swagger-ui/index.html"
    # Packages to include,多个用 , 分割
    packagesToScan: com.home.api.controller
    token: iolkiolk

2.在项目中增加过滤器

java 复制代码
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import java.io.IOException;

@WebFilter(urlPatterns = {"/v3/api-docs",
        "/swagger-ui.html"}, filterName = "springDocFilter")
public class SpringDocFilter implements Filter {

    private static final Logger log = LoggerFactory.getLogger(SpringDocFilter.class);

    @Value("${springdoc.swagger-ui.token}")
    private String swaggerToken;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        log.info("do springDocFilter,url:{}", request.getRequestURL());
        // 请求来源地址
        String referer = request.getHeader("referer");
        log.info("referer is {}", referer);

        /**
         * 1、请求来源地址为空,判断token是否匹配 
         */
        if (StringUtils.isBlank(referer)) {
            // 获取token
            String token = request.getParameter("token");
            log.info("token is {}", token);
            // 来源地址为空,判断token是否匹配
            if (!StringUtils.equals(swaggerToken, token)) {
                log.error("禁止未授权访问,url:{}", request.getRequestURL());
                response.setStatus(403);
                servletResponse.setContentType("application/json");
                servletResponse.setCharacterEncoding("UTF-8");
                //servletResponse.getWriter().write(JsonUtil.toJsonString(DJResult.error(-1, "禁止未授权访问", "")));
                servletResponse.getWriter().write( "禁止未授权访问");
                return;
            }
        } else if (!referer.contains(swaggerToken)) {
            log.warn("禁止未授权访问,url:{}", request.getRequestURL());
            response.setStatus(403);
            servletResponse.setContentType("application/json");
            servletResponse.setCharacterEncoding("UTF-8");
            servletResponse.getWriter().write( "禁止未授权访问");
            return;
        }

        filterChain.doFilter(servletRequest, servletResponse);

    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

}

3.配置好过滤器和yaml配置后,重启项目,输入localhost:8081/swagger-ui.html,过滤器会进行过滤

输入localhost:8081/swagger-ui.html?token=iolkiolk, (同时自定义路径会出现跳转到 http://localhost:8081/swagger-ui/index.html?token=iolkiolk )通过校验正常进入到文档

4.如果是生产环境,直接更改配置,springdoc.api-docs.enabled=false 和 springdoc.swagger-ui.enabled=false,不启用swagger

相关推荐
kfyty7252 分钟前
轻量级 ioc 框架 loveqq,支持接口上传 jar 格式的 starter 启动器并支持热加载其中的 bean
java·jvm·ioc·jar·热加载
G探险者26 分钟前
为什么 Zookeeper 越扩越慢,而 Nacos 却越扩越快?
分布式·后端
早起鸟儿27 分钟前
docker-Dockerfile 配置
java·linux·运维·docker
云边小网安32 分钟前
java集合篇(六) ---- ListIterator 接口
java·开发语言·青少年编程·java集合
都叫我大帅哥38 分钟前
Spring WebFlux:响应式编程的“未来战士”还是“花架子”?
java·spring·flux
都叫我大帅哥39 分钟前
Reactor 深度解析:响应式编程的「核反应堆」是如何工作的?
java·spring
不太厉害的程序员40 分钟前
NC65配置xml找不到Bean
xml·java·后端·eclipse
不被定义的程序猿41 分钟前
Golang 在 Linux 平台上的并发控制
开发语言·后端·golang
AntBlack1 小时前
Python : AI 太牛了 ,撸了两个 Markdown 阅读器 ,谈谈使用感受
前端·人工智能·后端
我在北国不背锅1 小时前
基于Java开发的浏览器自动化Playwright-MCP服务器
java·playwright·mcp