赞
踩
博主:爱码叔
个人博客站点: [icodebook](https://icodebook.com/)
公众号:爱码叔漫画软件设计(搜:爱码叔)
专注于软件设计与架构、技术管理。擅长用通俗易懂的语言讲解技术。对技术管理工作有自己的一定见解。文章会第一时间首发在个站上,欢迎大家关注访问!
本文讲解了Swagger的特性以及如何在java项目中使用Swagger。另外如果你的项目使用Gson作为接口的json转换工具,那么本文还告诉你如何让Swagger兼容Gson。最后也介绍了Swagger的局限性。
随着web系统前后端分离的流行,后端系统普遍采用RESTful API对前端系统提供服务。在这种情况下,我们一般采取的开发流程是这样的:
这个流程我们应该都很熟悉,这其中存在着很多让我们深有体会的问题,比如:
可以看出问题主要出在代码和文档脱节、人工维护接口文档以及人工维护接口测试访问上。那么,让我们看看今天要和大家分享的Swagger是否能够解决这些问题。
Swagger的目标是针对REST API定义标准的、语言无关的接口,使得人们及机器不用查看源代码、文档或者调用,就能够发现并理解api接口所能提供能的服务能力。从技术上讲swagger是一套规格说明,围绕他有着庞大的生态系统工具。
以上翻译自Swagger的官方网站,描述的有些抽象。具体来讲,swagger能为你提供有交互能力的api文档、文档或接口代码的自动生成、让接口具备可发现性。如此看来,swagger可以完全解决前面提出的问题。
Swagger的典型使用场景有如下三种:
如果你的项目已经有了大量的api接口,那么第二种场景比较适合你。我正在开发的项目也属于这种场景,所以本文主要讲解的是第二种场景下Swagger的应用。如何对既有接口没有代码侵入或者侵入很小的情况下,使用swagger为你的应用生成可被发现、有交互能力的接口文档。
前文讲到围绕Swagger有着庞大的生态系统。我们先来了解一下它的生态系统。图中蓝色矩形是生态系统中的工具。在这个生态系统中,用户最终的目的是通过Swagger UI查看Swagger文档,和API产生交互。
Swagger接口的描述文件是一个核心文件,支持Json及YAML格式。描述文档可以通过手工编写或者根据接口代码生成,Swagger UI把之呈现出来的,就是Swagger接口文档。
接下来,将讲解如何把既有的接口代码生成接口描述文件,并集成Swagger UI进行呈现。
首先,需要根据你的项目所用语言,在http://swagger.io/open-source-integrations/找到合适的类库。我的项目采用Spring mvc,我们可以找到springfox支持spring mvc和swagger的集成,所以接下来的工作就是如何把springfox集成到的项目之中。
springfox类库是基于spirng的生态系统对swagger规范的实现。所以它能够把spring mvc所写的接口转化为swagger接口文档。我们需要分如下几步来做:
1)引入springfox相关依赖
springfox使用了jackson,共需要引入如下依赖。
- "io.springfox:springfox-swagger2:2.5.0”,
-
"io.springfox:springfox-swagger-ui:2.5.0",
- "com.fasterxml.jackson.core:jackson-annotations:2.4.5",
- "com.fasterxml.jackson.core:jackson-databind:2.4.5",
- "com.fasterxml.jackson.core:jackson-core:2.4.5”,
-
"com.fasterxml:classmate:1.1.0”
2)配置springfox,创建SwaggerConfig类。
3)配置Swagger-UI的静态资源
在spring mvc的配置文件中加入如下配置:
- <mvc:resources mapping="/webjars/**" location=“classpath:/META-INF/resources/webjars/"/>
-
<mvc:resources mapping="swagger-ui.html" location="classpath:/META-INF/resources/“/>
如果你项目使用的Jackson做报文json转换,那么如上配置后swagger已经能正确运行了。访问http:www.xxxxx.com/v2/api-docs,可以看到swagger接口描述的json数据。访问http:www.xxxxx.com/swagger-ui.html,即可进入swagger UI的页面,在这里可以浏览所有接口,只需输入参数值即可调用接口。界面如下:
单个接口点开,界面如下,可以看到api的路径、输入参数、输出参数、状态码的值及说明都在这里了,进行测试的话,只需要修改一下输入参数然后点击try it out!。而以前在postman中,所有的一切都要你手工输入。
以上截图来自Swagger提供的在线示例,可以访问http://petstore.swagger.io/,亲自去体验一下。
如果你使用了Gson做你接口的json报文转换,那很不幸,Gson不能很好的支持springfox。
问题产生的原因在于springfox使用jackson做json的转化。springfox把要被转化为接口描述文档的json串,存放在它自己定义的Json对象中,Json对象代码如下:
value属性的值是整个json字符串。jackson进行json转换时会把value的值转化为json。正确的格式如下:
- {
- ”swagger”:”2.0”,
- ”info”:{
- ”description”:”无讼案例后台API接口文档”
- ………..
- }
- …...
- }
而Gson会把这个对象转化为json,转化完是下面这个样子:
- {
- "value": "{ \"swagger\": \"2.0\"},\"info\":{\"description\": \"无讼案例后台API接口文档\"}}"
- }
这样就造成swagger ui无法解析这个json。
解决这个问题我们需要做三件事情:
1、自定义Gson的typeAdapter来处理spingfox的Json对象。把Json对象里面value属性的值取出来做json转化。
2、继承spirng mvc的GsonHttpMessageConverter。重写构造方法,为Gson对象注册了自定义typeAdapter的。
3、修改Spring mvc配置文件,设置message converter为自定义的converter。
通过以上修改,你的所有接口还是用Gson进行报文转换,这样不会影响到既有的接口。而此同时,Swagger接口描述文件也能通过Gson正确生成了。我们再次访问http:www.xxxxx.com/swagger-ui.html。可以看到所有的接口被正确的展示出来了。
如果你的项目有拦截器做权限的校验,注意要放开以下两个地址:
否则请求被拦截后会导致无法正常显示swagger UI的界面。
通过以上的操作我们已经把swagger集成到了我们的项目中,swagger扫描现有接口代码自动生成Swaggr文档。在Swagger UI界面中,可以一目了然的看到所有的接口,查看接口的详情以及方便的调用。后续接口代码的任何变化都会立刻自动反应在Swagger文档中。这样Swagger解决了开篇提出的所有问题。是不是很完美?
此时我们得到的swagger接口文档还不够详尽,缺少对接口、参数的描述。这些我们可以通过对现有接口加注解的方式来解决,感兴趣的话可以查看swagger的文档。
另外Swagger可以通过把API分组的形式控制接口文档的访问。分组后,访问swagger ui页面时带上group参数,此时页面中只会展示本组下的api,这样可以区分对内、对外的API文档访问权限。
Swagger还可以传送api key参数,通过你自定义的拦截器做权限的控制。
范型类型的参数,无法在文档中生成json参数结构描述。这个问题可以通过定义一个指定类型的范型对象来变相的解决,此对象只用于采用注解的形式对接口参数进行描述。代码如下,其中LoginInfoResponseViewModel这个类指定了范型类型。
@ApiOperation(value = "用户登录", notes = "此接口用于用户登录",response=LoginInfoResponseViewModel.class)
这样做的话,需要写很多业务无关的类,仅是为了接口文档的呈现。
可见Swagger很好的解决了代码和文档不同步的问题,而且文档通过代码自动生成,节省了大量写文档的时间。通过swagger-ui可以很方便的纵观系统所能提供的全部接口,点击某个接口只需改动输入参数,即可调用接口,减少了接口测试过程中大量的手工工作。但其实要想让swagger生成详尽的文档·,还是需要编写大量注解,这个描述的工作时不可减少的。此外Swagger目前的问题也不能忽视。我们应该根据自己项目的实际情况来判断是否使用Swagger。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。