springboot3.x集成SpringDoc Swagger3

news2025/1/17 21:43:32

近期将springboox2.x升级到了3.x,索性将swagger2也同步升级到swagger3,具体过程如下。

一、添加maven依赖

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.1.0</version>
</dependency>

二、编写SpringDoc配置类

/**
 * spring doc配置
 */
@Configuration
public class SpringDocConfig {
    @Bean
    public OpenAPI restfulOpenAPI() {
        return new OpenAPI()
                .info(new Info().title("springboot3.x demo")
                        .description("Spring Boot3 Restful API")
                        .version("V1.0.0")
                        .license(new License().name("访问SpringDoc官方网站").url("http://springdoc.org")))
                .externalDocs(new ExternalDocumentation()
                        .description("欢迎访问LDY的技术博客")
                        .url("https://blog.csdn.net/ldy1016"));
    }

}

启动项目,在浏览器输入{ip}:{端口}/swagger-ui/index.html,查看效果,如127.0.0.1:8080/swagger-ui/index.html

三、添加swagger3注解

首先来看一下swagger2和swagger3中注解的对应关系,方便使用swagger2的同学升级到swagger3

swagger2swagger3说明
@Api@Tag用在请求的类上,表示对类的说明
@ApiIgnore@Hidden隐藏显示
@ApiImplicitParam@Parameter用在请求方法上,指定具体某一个请求参数的详细信息
@ApiImplicitParams@Parameters用在请求方法上,表示一组参数的说明
@ApiModel@Schema用于请求或者响应类上,说明请求或者响应数据
@ApiModelProperty@Schema用在属性上,描述响应类的属性用,swagger2中的hidden = true属性相当于swagger3中 的accessMode = READ_ONLY属性
@ApiOperation@Operation用在请求的方法上,说明方法的用途、作用对应注解中swagger2中的value和notes属性对应swagger3中的summary和description属性
@ApiParam@Parameter描述参数信息

 参考示例:

@Tag 描述整个类

@Tag(name = "用户管理")
@RestController
@RequestMapping("/user")
public class UserController {}

@Operation 用在请求的方法上,说明方法的用途、作用

    @Operation(summary = "查询用户列表接口",description = "部门用户信息")
    @GetMapping("/list")
    public List<UserVO> list(@RequestBody UserQueryParam param) {

        //TODO 查询用户信息并返回

        return null;
    }

@Schema 用于请求或者响应类上,说明请求或者响应数据,用在属性上,描述响应类的属性用

@Data
@Schema(title = "用户信息查询参数")
public class UserQueryParam implements Serializable {
    private static final long serialVersionUID = 4159622041608936674L;

    @Schema(title = "部门")
    private String department;

    @Schema(title = "姓名")
    private String name;

    @Schema(title = "性别",allowableValues = "0,1",example = "0")
    private Integer sex;

}

打开swagger页面查看效果

四、自定义过滤器,防止swagger文档未授权访问

swagger3未授权访问的路径主要包括/v3/api-docs/swagger-ui/index.html

本人提供的解决方案就是通过过滤器的方式对请求进行验证,请求的时候需要在链接后面加上我们自定义的token参数,通过验证token判断是否是合法的访问,注意,添加过滤器后需要在启动类上加上@ServletComponentScan注解才能生效,具体实现如下:

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

/**
 * 解决swagger-ui 未授权访问漏洞,需要在启动类加@ServletComponentScan注解
 * 
 * @author ldy
 * @since V1.0.0
 */
@Slf4j
@WebFilter(urlPatterns = {"/v3/api-docs",
        "/swagger-ui/index.html"}, filterName = "springDocFilter")
public class SpringDocFilter implements Filter {

    /**
     * 访问swagger的token
     */
    @Value("${swagger.token:123@abc}")
    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是否匹配 2、请求来源地址不为空,判断来源地址是否包含正确的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, "禁止未授权访问", "")));
                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(JsonUtil.toJsonString(DJResult.error(-1, "禁止未授权访问", "")));
            return;
        }


        filterChain.doFilter(servletRequest, servletResponse);
    }

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

通过添加如上所示的过滤器后,我们就可以通过在路径后面加上token参数进行访问文档地址了,如:127.0.0.1:8080/swagger-ui/index.html?token=123@abc

没有加token参数或者token参数匹配不上的请求会直接返回“禁止未授权访问”。这里的token尽量设置复杂一点。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

100 spring-security 中 /oauth/token 发送请求不携带参数 报错 “401 Unauthorized“

前言 最近存在这样的一个问题, 大致的复现方式是 访问 /oauth/token 接口, 然后不携带任何参数, 结果 服务器抛出了一个 "401 Unauthorized" 针对这个 401, 这里 梳理一下这个流程, 也会衍生出一些其他的问题 测试用例 客户端这边大致的情况是 构造参数, 然后发…

深入浅出Redis(六):Redis的主从架构与主从复制原理

引言 Redis是一款基于内存、键值对的非关系型数据库&#xff0c;它的性能十分的优秀&#xff0c;但单机节点的Redis还是存在许多不足的功能 单机无法保证高可用性&#xff0c;当单机Redis宕机时&#xff0c;无法继续提供服务&#xff0c;在主从架构 哨兵模式下能够解决无法保…

HCIA-Datacom题库(自己整理分类的)_33_DHCP协议多选【7道题】

1.使用动态主机配置协议DHCP分配IP地址有哪些优点? 可以实现IP地址重复利用 工作量大且不好管理 配置信息发生变化(如DNS),只需要管理员在DHCP服务器上修改,方便统一管理 避免IP地址冲突 2.网络中部署了一台DHCP服务器,但是管理员发现部分主机并没有正确获取到该DHCP服务…

开发一套pacs系统需要考虑哪些因素?

PACS全称Picture Archivingand Communication Systems。它是应用在医院影像科室的系统&#xff0c;主要的任务就是把日常产生的各种医学影像&#xff08;包括核磁&#xff0c;CT&#xff0c;超声&#xff0c;X光机&#xff0c;红外仪、显微仪等设备产生的图像&#xff09;通过各…

每日汇评:黄金上破2161美元纪录高位,有可能进一步上涨?

周四早间&#xff0c;金价在2150美元的历史高点附近盘整&#xff0c;并成功上破2160历史高位&#xff1b; 美元在美债收益率的压力下逐步走低&#xff0c;市场期待更多鲍威尔讲话和美国就业数据&#xff1b; 日线图上的RSI指标超买状况继续令黄金买家保持谨慎&#xff1b; 金价…

电脑蓝牙在哪里打开?不同系统详解

在现代计算机的多功能性中&#xff0c;蓝牙技术的广泛应用使得我们能够轻松连接各种外部设备&#xff0c;实现无线传输和分享。无论是连接无线耳机、键盘&#xff0c;还是与其他设备快速交换文件&#xff0c;蓝牙在电脑中的角色很重要。然而&#xff0c;对于一些用户而言&#…

ChatGPT提问技巧——标准提示

ChatGPT提问技巧——标准提示 标准提示是一种通过向模型提供一个具体要完成的任务&#xff0c;指导ChatGPT输出的简单方式。例如&#xff0c;如果你想生成一个新闻的总结&#xff0c;你要提供一个任务像这样的“总结一下这篇新闻文章“。 提示格式&#xff1a;”生成【任务】…

数组的内存执行原理

一.Java内存分配介绍 JVM虚拟机会在内存中执行程序 java内存分配介绍 方法区&#xff0c;栈&#xff0c;堆 首先将编译过后的.class文件送入方法区中。当类开始运行时将方法调入栈内存中&#xff0c;变量也是属于方法的&#xff0c;因此同方法一起进入栈内存中。当main方法要…

Java面试篇【MyCat】常见面试题(2024最新)

Mycat 1.Mycat 分库分表中间件&#xff0c;将存放在一个数据库的数据存放在不同的多个数据库中。来分散负载。 scheme 逻辑库&#xff0c;对应mysql的数据库&#xff0c;一个逻辑库定义了包含的所有table.是数据库集群对外的统一访问接口。table 逻辑表&#xff0c;和物理数…

C++的类与对象(三)

目录 类的6个默认成员函数 构造函数 语法 特性 析构函数 特性 对象的销毁顺序​​​​​​​ 类的6个默认成员函数 问题&#xff1a;一个什么成员都没的类叫做空类&#xff0c;空类中真的什么都没有吗&#xff1f; 基本概念&#xff1a;任何类在什么都不写时&#xff…

【Linux C | 网络编程】多播的概念、多播地址、UDP实现广播的C语言例子

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

[OpenWrt 22.03] ttylogin添加登录密码与禁止登录的配置

ttylogin 的使用 Openwrt 串口默认是没有密码的。Openwrt启动后,一个默认的密码将被启用去保护ssh登录和页面(http)登录,而串口登录密码却是空缺的。 对于 Openwrt,当内核初始化后,就会启动第一个进程 init,init进程会进行一系列的系统初始化工作,然后会读取 /etc/in…

vue 使用element plus 菜单时,折叠文字不消失

问题&#xff1a; 菜单折叠时&#xff0c;title文本无法消失&#xff0c;同时下拉箭头还会存在 解决方法&#xff1a; 查看项目中是否有div标签 原因 div和p标签都是块级元素&#xff0c;可能是这个原因 所以把项目中的p标签改为span标签 div改为template即可解决

java当中的栈和队列

一、Java中的栈 1.常用方法 注意上面的peek()方法和pop()方法的区别&#xff01; 2.实例 import java.util.Stack; public class StackTest { public static void main(String[] args) { Stack<String> stack new Stack<String>(); System.out.println(&qu…

Clion调试QT程序qDebug()、cout控制台无输出的可能解决方法

qDebug()不输出 在当前项目配置中添加一个环境变量 方法一、单独为配置 QT_ASSUME_STDERR_HAS_CONSOLE1 方法二、全局配置&#xff08;系统变量&#xff09; 一劳永逸 效果 cout不输出 Clion在debug调试C/C的时候&#xff0c;printf/cout不会实时输出情况 结果同上~ 谢阅…

NoSQL--2.MongoDB配置(Windows版)

目录 2.MongdoDB配置 2.1 Windows环境下操作 2.1.1 注册MongDB Atlas&#xff1a; 2.1.2 MongoDB Community Server Download&#xff1a; 2.1.3 启动MondgoDB服务&#xff1a; 2.1.3.1 命令行参数的方式启动MongoDB服务&#xff1a; 2.1.3.2 使用配置文件方式启动Mongo…

电脑怎么改照片大小kb?让你的照片尺寸更合适!

随着数字摄影的普及&#xff0c;我们经常需要处理各种大小的照片。有时候&#xff0c;为了上传至特定的网站或平台&#xff0c;或者为了节省存储空间&#xff0c;我们需要调整照片的大小&#xff0c;特别是其KB&#xff08;千字节&#xff09;值。那么&#xff0c;电脑怎么改照…

react tab选项卡吸顶实现

react tab选项卡吸顶实现&#xff0c;直接上代码&#xff08;代码有注释&#xff09; tsx代码 /* eslint-disable react-hooks/exhaustive-deps */ import React, { useEffect, useState } from "react"; import DocumentTitle from react-document-title import s…

【HTML】HTML基础7.2(有序列表)

目录 标签 效果 注意 标签 <ol> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> 。。。。。。 </ol> 效果 代码 <ol><li>银河护卫队 10000000000</li><l…

关于 selinux 规则

1. 查看selinux状态 SELinux的状态&#xff1a; enforcing&#xff1a;强制&#xff0c;每个受限的进程都必然受限 permissive&#xff1a;允许&#xff0c;每个受限的进程违规操作不会被禁止&#xff0c;但会被记录于审计日志 disabled&#xff1a;禁用 相关命令&#xf…