swagger-ui增强功能模块排序
创始人
2025-05-30 01:46:26
0

背景介绍

Swagger相关的网站推荐为https://swagger.io/和https://github.com/swagger-api和http://springfox.github.io/springfox/,更多的了解可以翻阅相关网站的第一手介绍。本文主要讲述的是基于springfox-swagger项目的一款ui组件swagger-bootstrap-ui,该项目提供的swagger-ui主题界面与国人行为习惯并不十分相符,由业内大神萧明提供的基于bootstrap主题的风格重构,一开始是一个增强swagger-ui的皮肤项目,后来经过持续的集成完善就用了swagger-bootstrap-ui项目。注意了,该项目的最终版本1.9.6已经停止更新,作者在2017年重启的knife4j项目作为持续更新与维护的swagger项目,后续的应用应该基于knife4j进行集成与应用(该项目与微服务架构的契合度更高;后端Java代码与前端ui分离开来;页面更加优雅酷炫;功能更加强大;)。

Swagger是一款为开发人员提供在线API接口文档的组件,无需额外开销即可对您的API执行简单的功能测试和接口规范预览,被全球数以千计的团队广泛地使用。项目中集成Swagger可以依据代码的集成实现Restful接口的文档规范,无需手动编写和维护文档,省去频繁变更文档的繁琐,同时提供有Web页面,服务于接口的在线执行功能,值得拥有。接口集成的优势:

(1)接口文档页面支持的展示信息齐全,页面包含有接口描述、请求地址、作者信息、输入参数、输出参数等;

(2)接口包含运行页面,可在页面进行后台接口的调用执行,支持各种请求类型和请求方式的请求,同时参数传递支持普通文本参数、枚举类型参数、数组集合类型、JSON对象类型等;

应用痛点

本篇文章主要主角是swagger-ui-bootstrap,并不是介绍如何去集成和应用此项目,重点是介绍页面应用时的功能模块下拉框较多时的功能快速定位的实现(由于并未使用knife4j,未知此项目是否已经存在官方的解决方案),实际单位项目的开发过程中,下拉框中的功能模块近乎50个了,多个功能模块命名是以中文开头,而swagger-ui页面中的功能模块下拉框对于中文的排序并不支持,所以在功能较多时找起来功能模块就显得非常费劲,故而就有了本文,经过前端与后端代码的分析,发现前端页面的功能实现并不能优雅的(不修改原始代码)解决这个问题,逐渐将解决方案放置从后端代码分析中,经过最后的逻辑分析与源码调试,发现可以定义一个Aop拦截获取功能模块的集合方法,将功能模块的集合数据进行排序即可。

改造方式

基于上述的问题点的改造方式也是崇尚优雅的改造为第一优先,即我们不修改源代码的任何地方,所以本次的改造称之为组件的增强,增强的实现不局限于swagger-bootstrap-ui项目,对于原始的swagger-ui项目也同样生效,因为增强的功能逻辑为springfox项目提供的原始代码,故而本次增强的关键点就在于Aop的方法拦截(项目中已经应用许久了,可放心集成),参考如下代码:

package cn.chendd.configuration;import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger2.annotations.EnableSwagger2;import java.util.List;/*** Swagger配置** @author chendd* @date 2019/9/16 13:16*/
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
public class SwaggerConfiguration {/*** swagger 组名称增强Aop*/@Component@Aspectpublic static class SwaggerGroupNameEnhanceAop {@Pointcut("execution(* springfox.documentation.swagger.web.InMemorySwaggerResourcesProvider.get())")public void pointcutDeclare() {}@Before("pointcutDeclare()")public void before(JoinPoint joinPoint) {}@Around("pointcutDeclare()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {Object returnValue;try {returnValue = joinPoint.proceed();this.sort(returnValue);} catch (Throwable e) {throw e;}return returnValue;}@After("pointcutDeclare()")public void after(JoinPoint joinPoint) {}/*** 排序逻辑实现,若仅仅实现按数字、英文字母、中文的顺序来排序,在功能模块过多时仍然存在一点点的识别难度,所以给模块名称前增加开头的字母。* 优势1:增加字母与-的分割,辨识度更高;* 优势2:在下拉框中可以直接点击英文或数字键,select下拉框会定位至开头匹配的option选项;* @param returnValue 数据* @noinspection unchecked*/private void sort(Object returnValue) {if (returnValue == null) {return;}if (! List.class.isAssignableFrom(returnValue.getClass())) {return;}List dataList = (List) returnValue;//排序数据dataList.sort((before , after) -> {String beforeName = toPinyin(before.getName());String afterName = toPinyin(after.getName());return StringUtils.compareIgnoreCase(beforeName , afterName);});//将排序后的按格式重新输出for (SwaggerResource resource : dataList) {String name = resource.getName();String pinyinName = toPinyin(name);resource.setName(Character.toUpperCase(pinyinName.charAt(0)) + " - " + name);}}/*** 汉子转换拼音* @param text 文本* @return 转换后的拼音*/static String toPinyin(String text) {if (StringUtils.isBlank(text)) {return text;}char[] cs = text.toCharArray();StringBuilder pinyinBuilder = new StringBuilder();HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();//输出设置,大小写,音标方式等defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);for (char c : cs) {//如果是中文if (c > 128) {try {String[] array = PinyinHelper.toHanyuPinyinStringArray(c, defaultFormat);if (array != null) {pinyinBuilder.append(array[0]);} else {pinyinBuilder.append(c);}} catch (BadHanyuPinyinOutputFormatCombination e) {throw new RuntimeException(e);}} else {pinyinBuilder.append(c);}}return pinyinBuilder.toString();}}}

顺便说一下增强功能点,给页面的功能下拉框提供了功能模块的拼音首字母,按照对应的首字母进行排序,排序规则默认使用Java的排序,特殊字符排第一、数字排第二、英文字母拍第三、中文排最后。所以本次除了增加Aop的方法拦截(环绕切面)外,还使用到了汉字转拼音,按照“字母大写 - 原始功能名称”的格式进行排序展示,参考增强后的运行效果截图:

(swagger-ui主题)

(swagger-bootstrap-ui主题)

由于切面的方法是springfox的代码,所以不仅swagger-bootstrap-ui的doc.html运行效果会生效,在swagger-ui的swagger-ui.html页面中同样生效。当然了,如果想实现功能模块前缀增加字母当然也可以有另外一种做法,就是在定义功能名称的时候手动增加字母的分割,当然了能否支持排序就不确定了,毕竟这种做法不是专业选手考虑事情事情的方式,自然也未尝验证。

特别说明

【2022/05/29补充】在后文中编写Spring Boot优雅的配置拦截器的时候,又将swagger中的【启用SwaggerBootstrapUi提供的增强功能】拿出来具体分析,后来发现无法开启的具体原因就是上述中增加了字母匹配的前缀导致,而该组件在进行实现的时候并为获取具体的值进行传递,而是将下拉框中的显示文本传递至后端导致无法正常的启用增强效果,故经过略微的分析后,于是准备在显示下拉框文本的时候显示格式化后的文本,而传递至Controller中时,再提供一个拦截器拦截处理增强请求的Controller方法,将方法的参数进行改写,改写完毕再通过AOP传递至具体的方法中来实现(注意:如下代码在swagger-bootstrap-ui分支中并不存在,可转至Interceptorji3后续的分支查看),增加@ConditionalOnBean注解,即当使用了Swagger的增强后才存在当前的方法过滤增强,详细参考如下代码所示:

/*** swagger 组名称修改,将传递过来的组名称还原为默认无前缀的名称*/
@Component
@ConditionalOnBean(value = SwaggerGroupNameEnhanceAop.class)
@Aspect
public static class SwaggerGroupNameExtAop {@Pointcut("execution(* com.github.xiaoymin.swaggerbootstrapui.web.SwaggerBootstrapUiController.apiSorts(..))")public void pointcutDeclare() {}@Before("pointcutDeclare()")public void before(JoinPoint joinPoint) {}@Around("pointcutDeclare()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {Object returnValue;try {Object[] args = joinPoint.getArgs();if (args[0] != null && args[0] instanceof String) {args[0] = args[0].toString().replaceAll("[A-Z] \\- " , "");}returnValue = joinPoint.proceed(args);} catch (Throwable e) {throw e;}return returnValue;}@After("pointcutDeclare()")public void after(JoinPoint joinPoint) {}
}

知识点介绍

(1)swagger-ui-bootstrap已经不更新了,除了使用最新版本1.9.6以外,可尝试使用knife4j新版本,官方网站:https://doc.xiaominfo.com;

(2)支持配置用户名和密码的授权验证,使得接口平台更加安全;

(3)支持API文档离线查看;

(4)支持全局参数设置,含query和header两种参数传递方式;

(5)支持个性化配置:国际化、请求参数缓存、分组tag显示、缓存已打开的api文档等;

(6)源码工程下载可转至https://gitee.com/88911006/chendd-blog-examples项目的swagger-bootstrap-ui分支;

(7)原为地址参考:https://www.chendd.cn/blog/article/1523485233473716225.html;

相关内容

热门资讯

【MySQL】锁 锁 文章目录锁全局锁表级锁表锁元数据锁(MDL)意向锁AUTO-INC锁...
【内网安全】 隧道搭建穿透上线... 文章目录内网穿透-Ngrok-入门-上线1、服务端配置:2、客户端连接服务端ÿ...
GCN的几种模型复现笔记 引言 本篇笔记紧接上文,主要是上一篇看写了快2w字,再去接入代码感觉有点...
数据分页展示逻辑 import java.util.Arrays;import java.util.List;impo...
Redis为什么选择单线程?R... 目录专栏导读一、Redis版本迭代二、Redis4.0之前为什么一直采用单线程?三、R...
【已解决】ERROR: Cou... 正确指令: pip install pyyaml
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
Lock 接口解读 前置知识点Synchronized synchronized 是 Java 中的关键字,...
Win7 专业版安装中文包、汉... 参考资料:http://www.metsky.com/archives/350.htm...
3 ROS1通讯编程提高(1) 3 ROS1通讯编程提高3.1 使用VS Code编译ROS13.1.1 VS Code的安装和配置...
大模型未来趋势 大模型是人工智能领域的重要发展趋势之一,未来有着广阔的应用前景和发展空间。以下是大模型未来的趋势和展...
python实战应用讲解-【n... 目录 如何在Python中计算残余的平方和 方法1:使用其Base公式 方法2:使用statsmod...
学习u-boot 需要了解的m... 一、常用函数 1. origin 函数 origin 函数的返回值就是变量来源。使用格式如下...
常用python爬虫库介绍与简... 通用 urllib -网络库(stdlib)。 requests -网络库。 grab – 网络库&...
药品批准文号查询|药融云-中国... 药品批文是国家食品药品监督管理局(NMPA)对药品的审评和批准的证明文件...
【2023-03-22】SRS... 【2023-03-22】SRS推流搭配FFmpeg实现目标检测 说明: 外侧测试使用SRS播放器测...
有限元三角形单元的等效节点力 文章目录前言一、重新复习一下有限元三角形单元的理论1、三角形单元的形函数(Nÿ...
初级算法-哈希表 主要记录算法和数据结构学习笔记,新的一年更上一层楼! 初级算法-哈希表...
进程间通信【Linux】 1. 进程间通信 1.1 什么是进程间通信 在 Linux 系统中,进程间通信...
【Docker】P3 Dock... Docker数据卷、宿主机与挂载数据卷的概念及作用挂载宿主机配置数据卷挂载操作示例一个容器挂载多个目...