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;

相关内容

热门资讯

安卓只恢复系统应用,重拾系统流... 你有没有遇到过这种情况?手机突然卡顿,或者某个应用突然罢工,你一气之下,直接开启了“恢复出厂设置”大...
安卓系统出现支付漏洞,揭秘潜在... 你知道吗?最近安卓系统可是闹出了不小的风波呢!没错,就是那个我们每天离不开的安卓系统,竟然出现了支付...
苹果换了安卓系统恢复,体验变革... 你有没有遇到过这种情况?手机里的苹果突然变成了安卓系统,而且还是那种让你摸不着头脑的恢复模式。别急,...
安卓怎么卸载系统app,轻松告... 手机里的系统应用越来越多,有时候真的让人眼花缭乱。有些应用虽然看起来很实用,但用起来却发现并不适合自...
安卓系统查看步数,揭秘日常运动... 你有没有发现,每天手机里的小秘密越来越多?今天,咱们就来聊聊安卓系统里那个悄悄记录你每一步的小家伙—...
安卓系统未来会不会,未知。 你有没有想过,那个陪伴我们手机生活的安卓系统,它的未来会怎样呢?想象每天早上醒来,手机屏幕上跳出的信...
安卓系统怎么设置截图,轻松捕捉... 亲爱的手机控们,你是不是也和我一样,有时候想记录下手机屏幕上的精彩瞬间呢?别急,今天就来手把手教你如...
安卓系统下载软件安装,安卓系统... 你有没有发现,手机里的安卓系统就像一个巨大的宝藏库,里面藏着各种各样的软件,让人眼花缭乱。今天,就让...
安卓10系统转移程序,轻松实现... 你有没有想过,当你从一台安卓手机升级到安卓10系统后,那些珍贵的照片、联系人、应用和数据怎么才能无缝...
安卓电脑强制重启系统,原因解析... 你有没有遇到过这种情况?你的安卓电脑突然间就强制重启了,屏幕上闪过一行行代码,你还没来得及保存文件,...
安卓怎么降低系统耗电,深度解析... 手机电量总是不够用,是不是你也和我一样,每天都要担心手机没电呢?别急,今天就来教你怎么给安卓手机降耗...
安卓系统的总体框架,架构与核心... 你有没有想过,你的手机里那个神奇的安卓系统,它到底是怎么运作的呢?今天,就让我带你一探究竟,揭开安卓...
谁的安卓系统好,谁家的安卓系统... 说到安卓系统,这可是个热门话题呢!你有没有想过,这么多安卓手机品牌,哪个的操作系统最让你心动?今天,...
安卓系统信付通,安全无忧的移动... 你知道吗?在安卓手机的世界里,有一个超级好用的支付工具,它就是信付通。今天,就让我带你来全方位了解一...
小米官方系统安卓包,深度解析与... 亲爱的数码爱好者们,你是否曾为手机系统而烦恼?市面上那么多手机品牌,各种操作系统让人眼花缭乱。今天,...
自制安卓手机双系统,自制安卓手... 你有没有想过,自己的手机可以同时运行两个操作系统呢?没错,就是那种安卓手机双系统!听起来是不是很酷?...
小米安卓系统怎么设置,科技前沿... 小米手机的用户们,是不是觉得安卓系统有点复杂,设置起来有点头疼呢?别担心,今天就来手把手教你如何轻松...
点歌系统支持安卓系统么,安卓用... 你有没有想过,在手机上点歌听歌,是不是也能像在KTV里那样随心所欲呢?现在,就让我来告诉你一个超级酷...
原版安卓系统刷机,解锁无限可能 你有没有想过,你的安卓手机其实可以焕然一新?没错,就是那种原汁原味的安卓系统,让你的手机重新找回当初...
欧尚改装安卓系统,打造智能驾驶... 你有没有想过,你的欧尚汽车其实也可以变身成为智能座驾呢?没错,就是那个你每天上下班的伙伴——欧尚,现...