基于OpenAPI、freemarker动态生成swagger文档

前言

spring项目中可以使用springfox或者springdoc,通过写注解的方式生成swagger文档,下面介绍一种不写注解,动态生成swagger文档的方式,在某些场景会适用,例如接口是动态生成的,此时swagger就不能通过注解来生成了。


一、定义swagger模板

通过观察一个swagger文档的openapi结构,将其中需要动态替换的部分写成变量,生成freemaker的ftl模板。
通过点击swagger图示链接可以查看openapi的json结构。
在这里插入图片描述
修改一个json结构,生成一个ftl模板,将模板放在springboot项目的resources/static/data-service-swagger-templates下面

{"openapi": "3.0.3","info": {"title": "通用查询-[${interfaceName}]接口","description": "通用查询接口","version": "0.0.1"},"servers": [{"url": "${dataServicePrefix}","description": "Generated server url"}],"security": [{"secretHeader": []}],"paths": {"${url}": {"post": {"tags": ["数据服务-通用查询接口"],"summary": "通用查询接口","description": "通用查询接口,请求体采用统一数据结构","operationId": "getData2UsingPOST","requestBody": {"content": {"application/json": {"schema": {"$ref": "#/components/schemas/DmoRequest"}}}},"responses": {"200": {"description": "OK","content": {"*/*": {"schema": {"$ref": "#/components/schemas/ResponseEntity"}}}},"201": {"description": "Created"},"401": {"description": "Unauthorized"},"403": {"description": "Forbidden"},"404": {"description": "Not Found"}}}}},"components": {"schemas": {"ResponseEntity": {"title": "ResponseEntity","type": "object","properties": {"desc": {"type": "string","description": "错误详细描述"},"message": {"type": "string","description": "如果为非200的返回,可以将此message提示给用户"},"requestURL": {"type": "string"},"stackTrace": {"type": "string","description": "后端的异常栈信息,如果过长,只截取前面一部分"},"status": {"type": "integer","description": "200:正常;401:未登陆;403:没有权限;400:请求参数校验失败;500:服务器内部错误","format": "int32"},"tookInMillis": {"type": "integer","description": "请求耗时","format": "int64"},"value": {"type": "object"}}},"DmoRequest": {"title": "DmoRequest","type": "object","properties": {"fulltextNode": {"$ref": "#/components/schemas/QueryNode"},"node": {"$ref": "#/components/schemas/QueryNode"},"pageNumber": {"type": "integer","description": "页码","format": "int32"},"pageSize": {"type": "integer","description": "每页条数","format": "int32"},"showColumns": {"uniqueItems": true,"type": "array","items": {"type": "string","description": "显示的列"}},"sorts": {"type": "array","items": {"$ref": "#/components/schemas/DmoSort"}}}},"QueryNode": {"title": "QueryNode","type": "object","description": "查询条件","properties": {"children": {"type": "array","items": {"$ref": "#/components/schemas/QueryNode"}},"data": {"$ref": "#/components/schemas/NodeData"},"type": {"type": "string","description": "节点类型","enum": ["AND", "LEAF", "OR", "ROOT"]}}},"NodeData": {"title": "NodeData","type": "object","description": "节点数据","properties": {"operator": {"type": "string","description": "操作符","enum": ["BETWEEN", "EQ", "EXISTS", "GE", "GT", "IN", "IS_NOT_NULL", "IS_NULL", "LE", "LIKE", "LT", "NE", "NOT_BETWEEN", "NOT_EXISTS", "NOT_IN", "NOT_LIKE", "PREFIX", "REGEXP"]},"param": {"type": "string","description": "参数名称,一般对应表的列名"},"value": {"type": "array","description": "参数值","items": {"type": "object"}}}},"DmoSort": {"title": "DmoSort","type": "object","description": "排序","properties": {"column": {"type": "string","description": "列名"},"sortOrder": {"type": "string","description": "排序方式","enum": ["ASC", "DESC"]}}}},"securitySchemes": {"secretHeader": {"type": "apiKey","name": "Authorization","in": "header"}}}
}

二、使用freemarker生成openapi的JSON结构

1.引入库

代码如下(示例):

<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.32</version>
</dependency>

2.生成json

下面的serviceInterface就是一个实体,可以自行定义

@ApiOperation(value = "获取openapi的JSON", notes = "获取openapi的JSON")@GetMapping("/swagger-json/{id}")public String getSwaggerJson(@ApiParam(value = "id") @PathVariable Integer id) throws BaseException {ServiceInterface serviceInterface = getServiceInterface(id);return getOpenApiJson(ServiceInterface serviceInterface, "test.ftl") ;}private String getOpenApiJson(ServiceInterface serviceInterface, String ftl) throws BaseException {freemarker.template.Configuration configuration = new 		freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_0);// 设置默认编码configuration.setDefaultEncoding("utf-8");//设置类加载器configuration.setClassLoaderForTemplateLoading(this.getClass().getClassLoader(), "data-service-swagger-templates");try {// 生成模板对象Template template = configuration.getTemplate(fileName);TEMPLATE_CACHE.put(fileName, template);} catch (Exception e) {throw new BaseException(String.format("获取模版文件:[%s]出错", fileName), e);}Template template = getFltTemplate(ftl);String dataServicePrefix = dataServiceProtocol + dataServiceUpstream;Map<String, String> dataMap = new HashMap<>();dataMap.put("interfaceName", serviceInterface.getServiceName());dataMap.put("dataServicePrefix", dataServicePrefix);dataMap.put("url", serviceInterface.getUrl());StringWriter sw = new StringWriter();try {template.process(dataMap, sw);return sw.toString();} catch (Exception e) {throw new BaseException("模板转换出错:" + e.getMessage(), e);}}

三、前端生成swagger示例

<!DOCTYPE html>
<html><head><title>数据服务接口文档</title><link rel="stylesheet" type="text/css" href="swagger-ui.css"/></head><body><div id="swagger-ui"></div><script src="swagger-ui-bundle.js"></script><script>window.onload = function () {SwaggerUIBundle({// url: "http://localhost:14500/v3/api-docs", // 替换成您的OpenAPI规范的URL或文件路径//  url: "swagger-custom-select.json", // 替换成您的OpenAPI规范的URL或文件路径url: "http://192.168.33.22:3282/dmo/service-interface/swagger-json/226", // 替换成您的OpenAPI规范的URL或文件路径dom_id: "#swagger-ui",deepLinking: true,});};</script></body>
</html>

其中url 为第二步的接口

用到的css和js下载地址:https://blog.csdn.net/weixin_41085315/article/details/124965953

四、测试

在这里插入图片描述

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

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

相关文章

Qt中QFile、QByteArray QDataStream和QTextStream区别及示例

在Qt中&#xff0c;QFile、QByteArray、QDataStream和QTextStream是常用的文件和数据处理类。 主要功能和区别 QFile&#xff1a; QFile是用于读写文本和二进制文件以及资源的I/O设备。可以单独使用QFile&#xff0c;或者更方便地与QTextStream或QDataStream一起使用。 通常在…

Cookie和Session

前言扩展&#xff1a;笔者在之前学习前端扫盲阶段&#xff0c;写过一个简单易读的&#xff1a;表白墙项目&#xff0c;具体的前端代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta ht…

mac安装+配置python3环境

一、python3下载 官网下载 https://www.python.org/ 二、python3安装 打开下载好的.pkg文件一直继续确认即可。 三、验证是否安装成功 打开终端&#xff0c;输入python3&#xff0c;如果返回python对应的版本信息&#xff0c;则安装成功。 四、python配置 如果需要输入…

基于卷积优化优化的BP神经网络(分类应用) - 附代码

基于卷积优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于卷积优化优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.卷积优化优化BP神经网络3.1 BP神经网络参数设置3.2 卷积优化算法应用 4.测试结果…

Qt窗体设计的布局

本文介绍Qt窗体的布局。 Qt窗体的布局分为手动布局和自动布局&#xff0c;手动布局即靠手工排布各控件的位置。而自动布局则是根据选择的布局类型自动按此类型排布各控件的位置&#xff0c;使用起来比较方便&#xff0c;本文主要介绍Qt的自动布局。 1.垂直布局 垂直布局就是…

基于WebRTC构建的程序因虚拟内存不足导致闪退问题的排查以及解决办法的探究

目录 1、WebRTC简介 2、问题现象描述 3、将Windbg附加到目标进程上分析 3.1、Windbg没有附加到主程序进程上&#xff0c;没有感知到异常或中断 3.2、Windbg感知到了中断&#xff0c;中断在DebugBreak函数调用上 3.3、32位进程用户态虚拟地址和内核态虚拟地址的划分 …

义乌再次位列第一档!2022年跨境电商综试区评估结果揭晓!

义乌跨境电商综试区捷报频传&#xff0c;在商务部公布的“2022年跨境电子商务综合试验区评估”结果中&#xff0c;中国&#xff08;义乌&#xff09;跨境电子商务综合试验区&#xff08;以下简称&#xff1a;“跨境综试区”&#xff09;评估结果为成效明显&#xff0c;综合排名…

【C++技能树】Lambda表达式

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 文章目录 0. Lambda表达式简介1. Lambda表达式2. Lambda表达式语法 0. Lambda表达式简介 在C98及之前,想要对sort进行自定义排序,或者对自定义类…

uniapp实现登录组件之外区域置灰并引导登录

实现需求 每个页面需要根据用户是否登录决定是否显示登陆组件,登录组件半屏底部显示,登录组件之外区域置灰,功能按钮点击之后引导提示登录.页面效果如下: 实现思路说明 设置登录组件背景颜色为灰色,将页面分成登录区域(底部)和非登陆区域(上面灰色显示部分), 置灰区域添加…

腾讯共享WiFi贴项目推广员是怎么收益的?

腾讯共享WiFi贴项目是一种非常普遍的商业共享模式&#xff0c;它为用户提供了便携、高速的无线网络服务。然而&#xff0c;人们对于这种项目是否真的能让共享WiFi贴推广员挣到钱还存在疑问。 腾讯共享WiFi贴扫码项目的运作方式是这样的&#xff1a;推广员将WiFi贴二维码粘贴到商…

Qt扫盲-QImage 理论总结

QImage 理论总结 一、概述二、读写图像文件三、图像信息四、像素操作1. 32位2. 8位 五、图像格式六、图像转换 一、概述 QImage类提供了一个独立于硬件的图像表示&#xff0c;允许直接访问像素数据&#xff0c;并且可以用作绘画设备。Qt提供了四个类来处理图像数据&#xff1a…

ES挂载不上怎么处理?

全文搜索 EelasticSearch安装 Docker安装 docker run -d --name es7 -e ES_JAVA_POTS"-Xms256m -Xmx256m" -e "discovery.typesingle-node" -v /home/206/es7/data/:/usr/share/elasticsearch/data -p 9200:9200 -p 9300:9300 elasticsearch:7.14.0 …

VS的使用时遇到了basePath不能是相对路径的问题,如何处理?

使用VS&#xff0c;当你编译运行代码时出现以下的问题 解决方法 原因&#xff1a;文件库的路径存在问题&#xff0c;需要把相对路径改为绝对路径。 如何解决&#xff1a;去右键点击解决方案&#xff0c;选择属性-》调试-》命令中的参数被设置为相对路径。就可以解决以上的问题…

【代码随想录第48天】动态规划7

代码随想录第48天| 动态规划7 322. 零钱兑换279.完全平方数 322. 零钱兑换 LeetCode题目&#xff1a; 322. 零钱兑换 代码随想录&#xff1a;322. 零钱兑换 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计…

(十二)Python文件操作(I/O)

和其它编程语言一样&#xff0c;Python 也具有操作文件&#xff08;I/O&#xff09;的能力&#xff0c;比如打开文件、读取和追加数据、插入和删除数据、关闭文件、删除文件等。 除了提供文件操作基本的函数之外&#xff0c;Python 还提供了很多模块&#xff0c;例如 fileinpu…

优质可视化素材大放送,全部免费,承包你今年的大屏项目

做大屏的时候&#xff0c;是不是经常遇到没有素材用的情况&#xff0c;也不知道从哪里可以下载到免费又酷炫的素材&#xff01;帆软君这就给你准备好了&#xff01; 还记得我们之前安利的FVD帆软视觉素材平台吗&#xff1f;最近上新了一波模板和视觉素材&#xff0c;都是从实战…

Pytorch深度学习快速入门—LeNet简单介绍(附代码)

一、网络模型结构 LeNet是具有代表性的CNN&#xff0c;在1998年被提出&#xff0c;是进行手写数字识别的网络&#xff0c;是其他深度学习网络模型的基础。如下图所示&#xff0c;它具有连狙的卷积层和池化层&#xff0c;最后经全连接层输出结果。 二、各层参数详解 2.1 INPUT层…

C++之函数重载【详解】

C之函数重载【详解】 1. 函数重载的概念2. C支持函数重载的原理(名字修饰)2.1 前言2.2 函数名修饰规则2.3 VS下的命名修饰规则 重载函数是函数的一种特殊情况&#xff0c;为方便使用&#xff0c;C允许在同一中声明几个功能类似的同名函数&#xff0c;但是这些同名函数的形式参数…

HarmonyOS 音频开发指导:使用 AudioRenderer 开发音频播放功能

AudioRenderer 是音频渲染器&#xff0c;用于播放 PCM&#xff08;Pulse Code Modulation&#xff09;音频数据&#xff0c;相比 AVPlayer 而言&#xff0c;可以在输入前添加数据预处理&#xff0c;更适合有音频开发经验的开发者&#xff0c;以实现更灵活的播放功能。 开发指导…

Redis --- 安装教程

Redis--- 特性&#xff0c;使用场景&#xff0c;安装 安装教程在Ubuntu下安装在Centos7.6下安装Redis5 特性在内存中存储数据可编程的扩展能力持久化集群高可用快速 应用场景实时数据存储作为缓存或者Session存储消息队列 安装教程 &#x1f680;安装之前切换到root用户。 在…