特别好用的swagger ui 封装
Swagger简单介绍
Swagger是一个Restful风格接口的文档在线自动生成和测试的框架
官网:http://swagger.io
官方描述:The World’s Most Popular Framework for APIs.
Swagger ui 的原生UI界面如下:
现在市面上的UI不足之处
1、原生UI显示的有些不够漂亮和清晰,特别是request 的model部分
2、每个服务都需要引入一套资源文件,不能作为一个中间件为其他API使用
3、默认通用配置繁琐,每个项目都需要复制重新配置一份swagger信息
后来在网上看到了别人封装的swagger-layer-ui,界面看起来不错,但是还是有些问题在。
新设计,新封装,即插即用
于是乎,结合上面的问题,采用了spring boot 的思想:约定大于配置,通用的配置全部帮大家封装好了,如有特殊业务,可单独配置
考虑到微服务和单服务版本的封装,做了一些特殊的打包配置:
微服务版本:中心UI服务需要访问API服务的接口,需要考虑一些跨域问题,简单的跨域问题,可以通过spring mvc配置来实现
单服务版本:即插即用,但是每个API服务需要加载一些资源包
我已经将代码上传到github上,有兴趣的小伙伴可以下载来看看。https://github.com/huanshare/huan-swagger
代码实现
huan-swagger-core(主要实现了一些swagger的默认配置,跨域通用配置,自定义注解的实现)
/**
* 实现了swagger的默认配置,和跨域问题
*/
@Configuration
public class HuanSwagger {
@Value("${swagger.enable:true}")
boolean enable;
@Value("${swagger.title:API查看器}")
String title;
@Value("${swagger.description:API服务的说明,请在配置文件中说明服务的作用}")
String description;
@Value("${swagger.contact.name:huanshare}")
String contactName;
@Value("${swagger.contact.url:www.huanshare.com}")
String contactUrl;
@Value("${swagger.contact.mail:huanshare@live.com}")
String contactMail;
@Value("${swagger.version:0.0.0}")
String version; public HuanSwagger() {
} @Bean
public Docket allApi() { if (!this.enable) {
return (new Docket(DocumentationType.SWAGGER_2)).select().apis(RequestHandlerSelectors.none()).paths(PathSelectors.none()).build();
} else {
ApiInfo apiInfo = (new ApiInfoBuilder()).title(this.title).description(this.description).contact(new Contact(this.contactName, this.contactUrl, this.contactMail)).version(this.version).build();
ApiSelectorBuilder builder = (new Docket(DocumentationType.SWAGGER_2)).useDefaultResponseMessages(false).apiInfo(apiInfo).select();
builder.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class));
return builder.build();
}
} @Bean
public CorsFilter apiCrosFilter() {
if (!this.enable) {
return new CorsFilter(new UrlBasedCorsConfigurationSource());
} else {
UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.setAllowCredentials(true);
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.addAllowedOrigin("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
}
/**
* 自定义注解,方便简单的注入
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@EnableSwagger2
@Import({HuanSwagger.class})
public @interface EnableHuanSwagger {
}
上面代码已经打成jar包,发布到maven库上了,具体版本使用
<dependency>
<groupId>com.github.huanshare</groupId>
<artifactId>huan-swagger-core</artifactId>
<version>1.0.1</version>
</dependency>
huan-swagger-ui(微服务UI项目)
layui.config({
base: 'assets/layext/'
}).extend({
nlaytpl: 'nlaytpl',
ncmntool: 'ncmntool',
nswagger: 'nswagger',
nupload: 'nupload'
});
//
layui.use(['layer', 'element', 'form', 'nlaytpl', 'nswagger', 'ncmntool', 'upload'], function () {
var $ = layui.jquery,
layer = layui.layer,
element = layui.element,
form = layui.form,
ncmntool = layui.ncmntool,
nlaytpl = layui.nlaytpl,
nswagger = layui.nswagger; $(".logo").click(function () {
$(".nav-home").click();
$(".layui-side-scroll").scrollTop(0);
}); $("#iptApiUrl, .btn-clearurl").on('mouseover', function () {
$(".btn-clearurl").show();
}).on('mouseout', function () {
$(".btn-clearurl").hide();
});
$(".btn-clearurl").click(function () {
$("#iptApiUrl").val('');
});
$(".btn-gourl").click(function () {
// 清理数据
$(".api-main").empty();
// 弹出加载框
var loader = layer.load();
// 拉取数据
var iptApiUrl = $("#iptApiUrl").val() || location.hash;
if (iptApiUrl.charAt(0) == "#") {
iptApiUrl = iptApiUrl.substr(1);
}
if (iptApiUrl == "") {
iptApiUrl = location.protocol + "//" + location.host + "/v2/api-docs";
if (location.search && location.search.indexOf("_ijt=") != -1) {
iptApiUrl = "example.json";
}
}
if (iptApiUrl != "example.json") {
if (!/\/v2\/api-docs$/.test(iptApiUrl)) {
iptApiUrl = iptApiUrl + "/v2/api-docs";
} if (!/^http/.test(iptApiUrl)) {
iptApiUrl = "http://" + iptApiUrl;
}
}
$("#iptApiUrl").val(iptApiUrl);
// 获取配置文档
$.ajax({
url: iptApiUrl,
dataType: "json",
type: "get",
success: function (apidoc) {
// 解析数据
try {
nswagger.resolve(apidoc);
} catch (e) {
layer.msg('解析失败,请确认文档配置是否正确', {icon: 5});
console.error(e);
return;
}
// 设置页面标题
document.title = apidoc.info.title;
// 设置页面LOGO
ncmntool.checkimg(apidoc.schemes[0] + "://" + apidoc.host + "/logo.png", function (imgurl) {
$(".logo img").attr("src", imgurl);
});
location.hash = apidoc.host;
// 渲染左侧菜单导航
nlaytpl.render(".api-main")("comp/tplApiMain.html", {tags: apidoc["tags"]}, function () {
// 重新渲染菜单效果
element.init();
// 监听导航点击事件
element.on("nav(left-nav)", function (ele) {
if ($(ele).hasClass("nav-home")) {
nlaytpl.render(".main-body")("comp/tplHomeBody.html", apidoc, function () {
// 重新渲染组件效果
element.init();
});
} else {
$((".layui-nav-itemed")).removeClass(("layui-nav-itemed"));
$(ele).parents(".layui-nav-item").addClass("layui-nav-itemed");
var _a = $(ele).children(':first-child');
$(".layui-side-scroll").scrollTop($(_a).offset().top - $(".layui-side").offset().top + $(".layui-side").scrollTop());
var _dpath = $(_a).attr("dpath"), _dhttpmethod = $(_a).attr("dhttpmethod");
nlaytpl.render(".main-body")("comp/tplApiBody.html", {
apidoc: apidoc,
tagname: $(_a).attr("dtag"),
dpath: _dpath,
dhttpmethod: _dhttpmethod,
mmeta: apidoc["paths"][_dpath][_dhttpmethod]
}, function () {
// 重新渲染组件效果
element.init();
form.render();
});
}
});
// 监听处理导航的悬浮提示
$('.layui-nav-item a[dtitle]').on('mouseover', function () {
var that = this;
layer.tips($(that).attr("dtitle"), that, {
time: 0
});
}).on('mouseout', function () {
layer.closeAll('tips');
});
// 渲染主页
$(".nav-home a").click();
});
// 渲染顶部导航搜索
nlaytpl.render(".api-quick")("comp/tplApiQuick.html", {tags: apidoc["tags"]}, function () {
form.on('select(api-quick)', function (data) {
var pm = data.value.split("::");
$(".left-nav a[dpath='" + pm[1] + "'][dhttpmethod='" + pm[0] + "']").click();
});
// 重新渲染表单组件效果
form.render("select");
});
},
error: function () {
layer.msg('加载失败,请确认API文档的地址是否正确', {icon: 5});
},
complete: function () {
layer.close(loader);
}
});
}).on('mouseover', function () {
var that = this;
layer.tips("点击加载目标地址的API文档", that, {
time: 0,
tips: 3
});
}).on('mouseout', function () {
layer.closeAll('tips');
});
//
$(".btn-gourl").click();
});
swagger-ui-layer(单服务版本,即插即用),JS代码同huan-swagger-ui类似,只是引入jar包不同
<dependency>
<groupId>com.github.huanshare</groupId>
<artifactId>swagger-ui-layer</artifactId>
<version>1.0.0</version>
</dependency>
使用说明
项目描述
由于考虑到大家的使用情况,结合网上 swagger-ui-layer的封装情况 现把 swagger-layui 分为 微服务版,单服务版。目前只支持 RestController
1)微服务版本:微服务与 layui 分离,layui 部署到新服务器上,供各个服务使用
demo例子:http://106.12.9.238:8080/webjars/swagger-ui/index.html#106.12.9.238:8081
2)单服务版本:layui 部署在服务上,即插即用,非常方便
项目结构
huan-swagger-core swagger核心组件封装
swagger-ui-layer 单服务版本:供单服务即插即用
huan-swagger-ui 微服务版本:swagger UI页面,作为一个第三方服务来渲染接口,用来渲染远程服务器的接口说明 (aa.com)
spring-boot-demo swagger 微服务测试页面 (bb.com)
spring-mvc-demo swagger spring mvc单服务测试页面 (bb.com)
微服务访问形式:http://aa.com/webjars/swagger-ui/index.html#http://bb.com
微服务demo实例:http://106.12.9.238:8080/webjars/swagger-ui/index.html#106.12.9.238:8081
使用说明(spring boot)
一、微服务版本:
1、部署到服务器上:huan-swagger-ui项目
2、微服务项目修改
1) pom依赖
<dependency>
<groupId>com.github.huanshare</groupId>
<artifactId>huan-swagger-core</artifactId>
<version>1.0.1</version>
</dependency>
2) spring boot项目启动项添加:
@EnableHuanSwagger
3) application.yml配置 (可选项配置)
# Swagger设置 enable 默认为true,为false时,关闭接口展示
swagger:
enable: true,
version: 版本号
title: 项目标题
description: 项目描述
contact:
name: 用户名
url: url地址
mail: 邮箱
3、页面访问:UI服务器地址/webjars/swagger-ui/index.html#API-服务器地址
4、具体使用方式,请参考 huan-swagger-test
二、单服务版本:
1、服务项目修改
1) pom依赖
<dependency>
<groupId>com.github.huanshare</groupId>
<artifactId>swagger-ui-layer</artifactId>
<version>1.0.0</version>
</dependency>
2) spring boot项目启动项添加:
@EnableHuanSwagger
3) application.yml配置 (可选项配置)
# Swagger设置 enable 默认为true,为false时,关闭接口展示
swagger:
enable: true,
version: 版本号
title: 项目标题
description: 项目描述
contact:
name: 用户名
url: url地址
mail: 邮箱
3、页面访问:UI服务器地址/api-doc.html
三、修改首页图标:根目录/logo.png(将图片地址映射到根目录下进行访问)
使用说明(spring mvc)
1、微服务版本:API需要在 添加pom依赖,需要手动解决跨域问题,具体可参考 spring-mvc-demo中的CORSFilter与web.xml中的跨域配置, 可参考 spring-mvc-demo---》CORSFilter
1) pom依赖
<dependency>
<groupId>com.github.huanshare</groupId>
<artifactId>huan-swagger-core</artifactId>
<version>1.0.1</version>
</dependency>
2) Bean注入,Filter配置
@Configuration
@EnableHuanSwagger
@EnableWebMvc
public class CORSFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
chain.doFilter(req, res);
}
}
3) web.xml中配置过滤器
<filter>
<filter-name>cors</filter-name>
<filter-class>com.huanshare.springMvcDemo.config.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、单服务版本:添加pom依赖,注入各种Bean,可参考 spring-mvc-demo --》MySwaggerConfig
1) pom依赖
<dependency>
<groupId>com.github.huanshare</groupId>
<artifactId>swagger-ui-layer</artifactId>
<version>1.0.0</version>
</dependency>
2) Bean注入
@Configuration
@EnableHuanSwagger
@EnableWebMvc
public class MySwaggerConfig {
}
3、修改首页图标:根目录/logo.png(将图片地址映射到根目录下进行访问)
特点
原来看过其他小伙伴的源码,页面交互不算太理想
无论单机版还是微服务版,整体UI在小伙伴基础上做了一些修改,整体内容进行了封装,不需要配置一些额外的选项,即插即用,非常方便
微服务版:实现了API与UI的分离,但是需要为UI单独部署一套服务器,增加了其他成本;如果微服务多的话,这也算是个不错的方案
单服务版:简单配置,即插即用,非常方便
小伙伴的地址(https://github.com/ohcomeyes/swagger-ui-layer )
特别好用的swagger ui 封装的更多相关文章
- Swagger UI使用指南
1:认识Swagger Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法 ...
- Swagger UI in AspNetCore WebAPI
Swagger其实包含了三个部分,分别是Swagger Editor文档接口编辑器,根据接口文档生成code的Swagger Codegen,以及生成在线文档的Swagger UI.在AspNetCo ...
- ABP框架 - Swagger UI 集成
文档目录 本节内容: 简介 Asp.net Core 安装 安装Nuget包 配置 测试 Asp.net 5.x 安装 安装Nuget包 配置 测试 简介 来自它的网页:“...使用一个Swagger ...
- ABP理论学习之Swagger UI集成
返回总目录 本篇目录 介绍 安装 安装Nuget包 配置 测试 介绍 从官方网站上可以看到:"启用了Swagger API,就可以获得交互式文档,生成和发现客户端SDK". 安装 ...
- ASP.NET Core 在 Swagger UI 中显示自定义的 Header Token
Swagger 是个好东西,对于前后端分离的网站来说,不仅是提高前后端开发人员沟通效率的利器,也大大方便了后端人员测试 API.有时候,API 中可能需要在 Header 中设置认证参数,比如 aut ...
- 在Abp中集成Swagger UI功能
在Abp中集成Swagger UI功能 1.安装Swashbuckle.Core包 通过NuGet将Swashbuckle.Core包安装到WebApi项目(或Web项目)中. 2.为WebApi方法 ...
- TP框架整合Swagger UI接口文档
1.下载swagger ui:http://swagger.io/swagger-ui/: 2.在应用目录里新建一个目录xxx:如图 3.解压后把dist目录的所有文件拷贝到新建的目录里面: 4.在新 ...
- 使用 Swagger UI 与 Swashbuckle 创建 RESTful Web API 帮助文件
作者:Sreekanth Mothukuru 2016年2月18日 本文旨在介绍如何使用常用的 Swagger 和 Swashbuckle 框架创建描述 Restful API 的交互界面,并为 AP ...
- gRPC helloworld service, RESTful JSON API gateway and swagger UI
概述 本篇博文完整讲述了如果通过 protocol buffers 定义并启动一个 gRPC 服务,然后在 gRPC 服务上提供一个 RESTful JSON API 的反向代理 gateway,最后 ...
随机推荐
- 什么是AOP和OOP,IOC和DI有什么不同?
什么是AOP和OOP,IOC和DI有什么不同? 解答: 1)面向对象编程(Object Oriented Programming,OOP,面向对象程序设计)是一种计算机编程架构.AOP是OOP的延续, ...
- char类型能否存储一个中文字符?为什么
char类型能否存储一个中文字符?为什么 解答:可以.一个char是两个字节,而一个中文也是两个字节.
- 【Python】Webpy
http://webpy.org/install.zh-cn 官网学习,对于No socket could be created 一般是默认的8080端口已经被某些服务占用,可以换一个端口.
- herf 和 src 的区别
1.herf 表示超文本引用(hypertext reference),指向网络资源所在位置,建立和当前元素( 锚点)或当前文档(链接)之间的链接,如果我们在文档中添加 <link href=& ...
- PowerDesigner最基础的使用方法入门学习2
from:http://www.cnblogs.com/huangcong/archive/2010/06/14/1757957.html 最近要忙期考,但还是决定每天抽点空来写CodeSmith的系 ...
- cocos2d-x-3.6 引擎基础概念
先讲一下引擎里面几个重要的基础概念:导演.节点,场景.层,精灵. 当然实际开发人员会碰到非常多其它概念,不过不要紧.有了这些基础概念,后面自己学习起来就easy多了. 节点(Node)是cocos2d ...
- 下载xftp,xshell进行与linux端的远程操作
在window下下载xftp5和xshell5 xshell主要是对远程的及其进行访问,在远程的情况下进行操作 xftp可以对远程的机器进行文件传输. 我安装这两个是单个的安装的. 进入官网 http ...
- iOS-更新CocoaPods出现错误 提示重复文件
当多人开发的时候,或者引入了一些别人的第三方库文件的时候,当我们再更新CocoaPods时会出现错误,错误提示有一些文件 出现重复,这个时候我们需要查看一些是什么文件出现了重复,错误提示是xxxx三方 ...
- 将BT转为磁力链接
实战代码 安装完成后,我们来看下代码: 系统环境:Linux Python环境:Python2.7 请注意python版本 bt2url.py 1 2 3 4 5 6 7 8 9 10 11 12 1 ...
- Kotlin——中级篇(二): 属性与字段详解
在前面的章节中,详细的为大家讲解到了Kotlin中对类的类的定义.使用.初始化.初始化.类继承等内容,但是在一个类中,几乎上是不可能不出现属性与字段(field)的,这一篇文章就为大家奉上Kotlin ...