Swagger是一個Restful風格接口的文檔在線自動生成和測試的框架
官網:http://swagger.io
官方描述:The World’s Most Popular Framework for APIs.html
Swagger ui 的原生UI界面以下:jquery
一、原生UI顯示的有些不夠漂亮和清晰,特別是request 的model部分 git
二、每一個服務都須要引入一套資源文件,不能做爲一箇中間件爲其餘API使用github
三、默認通用配置繁瑣,每一個項目都須要複製從新配置一份swagger信息web
後來在網上看到了別人封裝的swagger-layer-ui,界面看起來不錯,可是仍是有些問題在。ajax
因而乎,結合上面的問題,採用了spring boot 的思想:約定大於配置,通用的配置所有幫你們封裝好了,若有特殊業務,可單獨配置spring
考慮到微服務和單服務版本的封裝,作了一些特殊的打包配置:json
微服務版本:中心UI服務須要訪問API服務的接口,須要考慮一些跨域問題,簡單的跨域問題,能夠經過spring mvc配置來實現api
單服務版本:即插即用,可是每一個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
1、微服務版本:
一、部署到服務器上:huan-swagger-ui項目
二、微服務項目修改
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: 郵箱
三、頁面訪問:UI服務器地址/webjars/swagger-ui/index.html#API-服務器地址
四、具體使用方式,請參考 huan-swagger-test
2、單服務版本:
一、服務項目修改
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: 郵箱
三、頁面訪問:UI服務器地址/api-doc.html
3、修改首頁圖標:根目錄/logo.png(將圖片地址映射到根目錄下進行訪問)
一、微服務版本: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>
二、單服務版本:添加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 { }
三、修改首頁圖標:根目錄/logo.png(將圖片地址映射到根目錄下進行訪問)
原來看過其餘小夥伴的源碼,頁面交互不算太理想
不管單機版仍是微服務版,總體UI在小夥伴基礎上作了一些修改,總體內容進行了封裝,不須要配置一些額外的選項,即插即用,很是方便
微服務版:實現了API與UI的分離,可是須要爲UI單獨部署一套服務器,增長了其餘成本;若是微服務多的話,這也算是個不錯的方案
單服務版:簡單配置,即插即用,很是方便
小夥伴的地址(https://github.com/ohcomeyes/swagger-ui-layer )