使用springfox+swagger2书写API文档(十八)


使用springfox+swagger2书写API文档

springfox是通过注解的形式自动生成API文档,利用它,可以很方便的书写restful API,swagger主要用于展示springfox生成的API文档,笔者将主要介绍springfox的配置与使用,文中spring版本为4.2.6.RELEASE,springfox版本为2.6.1,使用Maven进行项目依赖管理。

Maven依赖配置

下面是Maven pom.xml配置信息

<properties> <springfoxversion>2.6.1</springfoxversion> </properties> <dependencies> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${springfoxversion}</version> <scope>compile</scope> </dependency> </dependencies>

 

如果启动项目时出现com/fasterxml/jackson/databind/ObjectMapper类找不到,请加入下面依赖

<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.6.6</version> </dependency>

 

Configuration类配置

下面是基础配置类,下面类中的.apiInfo()可以去掉,不使用也可以。

/* 省略 package name */ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration //必须存在 @EnableSwagger2 //必须存在 @EnableWebMvc //必须存在 @ComponentScan(basePackages = {"org.blog.controller"}) //必须存在 扫描的API Controller package name 也可以直接扫描class (basePackageClasses) public class WebAppConfig{ @Bean public Docket customDocket() { // return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()); } private ApiInfo apiInfo() { Contact contact = new Contact("周发扬", "https://cc520.me", "yangyang_666@icloud.com"); return new ApiInfo("Blog前台API接口",//大标题 title "Blog前台API接口",//小标题 "0.0.1",//版本 "www.fangshuoit.com",//termsOfServiceUrl contact,//作者 "Blog",//链接显示文字 "https://cc520.me"//网站链接 ); } }

 

注意:当前类一定要让spring在加载时候能扫描到配置类。

springfox使用

添加了配置类,我们开始创建一个Controller类(一定要让上一步配置类中的@ComponentScan扫描到),并在类中使用注解配置API信息。
下面类中没有添加全局异常处理,如果传递的参数类型和接收类型不匹配等情况,会抛出异常信息,请自行添加全局异常处理。

/* *省略package 和 部分 improt */ import io.swagger.annotations.*; @Controller @RequestMapping(value = "/v1/api") public class HomeApiController{ //这里使用POST @RequestBody必须使用POST才能接收,这里方便讲解 @ApiOperation(value = "一个测试API", notes = "第一个测试API") @ResponseBody @RequestMapping(value = "/test/{path}", method = RequestMethod.POST) @ApiImplicitParams({ @ApiImplicitParam(name = "blogArticleBeen", value = "文档对象", required = true, paramType = "body", dataType = "BlogArticleBeen"), @ApiImplicitParam(name = "path", value = "url上的数据", required = true, paramType = "path", dataType = "Long"), @ApiImplicitParam(name = "query", value = "query类型参数", required = true, paramType = "query", dataType = "String"), @ApiImplicitParam(name = "apiKey", value = "header中的数据", required = true, paramType = "header", dataType = "String") }) public JSONResult test(@RequestBody BlogArticleBeen blogArticleBeen, @PathVariable Long path, String query, @RequestHeader String apiKey, PageInfoBeen pageInfoBeen){ System.out.println("blogArticleBeen.getLastUpdateTime():"+blogArticleBeen.getLastUpdateTime()); System.out.println("blogArticleBeen.getSorter():"+blogArticleBeen.getSorter()); System.out.println("path:"+path); System.out.println("query:"+query); System.out.println("apiKey:"+apiKey); System.out.println("pageInfoBeen.getNowPage():"+pageInfoBeen.getNowPage()); System.out.println("pageInfoBeen.getPageSize():"+pageInfoBeen.getPageSize()); JSONResult jsonResult = new JSONResult(); jsonResult.setMessage("success"); jsonResult.setMessageCode(null); jsonResult.setCode(0); jsonResult.setBody(null); return jsonResult; } }

 

BlogArticleBeen.java

//省略 package import public class BlogArticleBeen { private Long id; private String name; //标题 private String mainPhoto; //封面图片 private String sketch; //简述 private String content; //详细描述 private String contentMd; //详细描述 markdown private Boolean ifTop; //是否置顶 private String sources; //来源 private String staticCode; //静态码 private BigDecimal sorter; private Boolean status; //状态 @ApiModelProperty(hidden = true) private String creater; @ApiModelProperty(dataType = "java.util.Date") private Timestamp lastUpdateTime; @ApiModelProperty(dataType = "java.util.Date") private Timestamp creatTime; private String columnNamesCache; private String columnIdsCache; private String labelIdsCache; private String labelNamesCache; //省略 set get }

 

PageInfoBeen.java

//省略 package import public class PageInfoBeen { @ApiParam(value = "当前页", required = true) private Integer nowPage; @ApiModelProperty(value = "每页大小", required = true) private Integer pageSize; //省略 set get }

 

JSONResult.java

//省略 package import public class JSONResult { private String message; private int code = -1; private String messageCode; private Object body; //省略 set get }

 

完成以上操作,我们就已经可以实际看到springfox为我们生成的API json字符串了,重启服务器,在浏览器中访问http://127.0.0.1:port/v2/api-docs(如果添加了group信息,请参考springfox官方文档),出现下图展示的信息说明配置正确。

8DCAB7F8-832C-4596-9386-E62F4FA1190C.png

如果没有得到这个结果,检查一下是否更换了MessageConverter为fastjson的,如果有,请升级fastjson为最新版本再测试。

####springfox、swagger.annotations.*注解部分参数介绍
在上面只展示了如何使用,这里将对上面添加的swagger注解进行说明,笔记使用时参考了swagger annotations Api 手册,接下来进行部分常用注解使用说明介绍。
- @ApiIgnore 忽略注解标注的类或者方法,不添加到API文档中

  • @ApiOperation 展示每个API基本信息

    • value api名称
    • notes 备注说明
  • @ApiImplicitParam 用于规定接收参数类型、名称、是否必须等信息

    • name 对应方法中接收参数名称
    • value 备注说明
    • required 是否必须 boolean
    • paramType 参数类型 body、path、query、header、form中的一种
      • body 使用@RequestBody接收数据 POST有效
      • path 在url中配置{}的参数
      • query 普通查询参数 例如 ?query=q ,jquery ajax中data设置的值也可以,例如 {query:”q”},springMVC中不需要添加注解接收
      • header 使用@RequestHeader接收数据
      • form 笔者未使用,请查看官方API文档
    • dataType 数据类型,如果类型名称相同,请指定全路径,例如 dataType = “java.util.Date”,springfox会自动根据类型生成模型
  • @ApiImplicitParams 包含多个@ApiImplicitParam

  • @ApiModelProperty 对模型中属性添加说明,例如 上面的PageInfoBeen、BlogArticleBeen这两个类中使用,只能使用在类中。

    • value 参数名称
    • required 是否必须 boolean
    • hidden 是否隐藏 boolean
      其他信息和上面同名属性作用相同,hidden属性对于集合不能隐藏,目前不知道原因
  • @ApiParam 对单独某个参数进行说明,使用在类中或者controller方法中都可以。注解中的属性和上面列出的同名属性作用相同

以上为主要常用的注解介绍,请结合springfox使用查看

使用swagger2展示API文档

通过上述配置,我们已经完成了API数据生成,现在我们只需要使用swagger2 UI展示API文档即可
访问github:下载swagger-ui,下载zip文件,解压后把里面的dist目录下的所有文件考入springMVC的静态资源下,修改拷贝的index.html文件,替换下面的js代码:

var baseUrl = ""; $(function () { var url = window.location.search.match(/url=([^&]+)/); if (url && url.length > 1) { url = decodeURIComponent(url[1]); } else { //上面描述的api-docs地址 url = baseUrl + "/v2/api-docs"; } // Pre load translate... if (window.SwaggerTranslator) { window.SwaggerTranslator.translate(); } window.swaggerUi = new SwaggerUi({ url: url, validatorUrl: undefined, dom_id: "swagger-ui-container", supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'], onComplete: function (swaggerApi, swaggerUi) { if (typeof initOAuth == "function") { initOAuth({ clientId: "your-client-id", clientSecret: "your-client-secret-if-required", realm: "your-realms", appName: "your-app-name", scopeSeparator: ",", additionalQueryStringParams: {} }); } if (window.SwaggerTranslator) { window.SwaggerTranslator.translate(); } $('pre code').each(function (i, e) { hljs.highlightBlock(e) }); addApiKeyAuthorization(); }, onFailure: function (data) { log("Unable to Load SwaggerUI"); }, docExpansion: "none", jsonEditor: false, apisSorter: "alpha", defaultModelRendering: 'schema', showRequestHeaders: false }); //这里可以添加权限认证,例如token function addApiKeyAuthorization() { var token = "you-token"; var tokenHeader = new SwaggerClient.ApiKeyAuthorization("token", token, "header"); window.swaggerUi.api.clientAuthorizations.add("token", tokenHeader); } window.swaggerUi.load(); function log() { if ('console' in window) { console.log.apply(console, arguments); } } });

 

完成了以上配置,直接访问修改的index.html,出现下面页面表示成功:
521F2063-0EFD-4A08-BD71-000D6AD27D90.png

1E176526-C913-45DB-8716-D7AA63D74F75.png

总结

通过以上步骤已经完成基本springfox+swagger-ui的基本配置,其他更新详细使用方法请查看springfox官网swagger官网,如文章中有错误信息,请联系笔者进行更改。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM