SpringBoot2.x整合Swagger2,远离编写繁重的接口文档

后台开发人员最痛苦的是什么,或许不是写接口,而是写接口文档。接口文档真是体力活,没有什么技术含量,粘贴复制还要心细,能把人累到吐血。呃,写接口文档的那些日子痛不欲生、苦不堪言。希望有那么一天,可以脱离写接口文档的苦海。

这样的一天很快到来了,那就是接触了swagger框架。刚开始,心里满满的兴奋,是不是稍微配置一下,就能摆脱写文档的苦海呢,事实却说,没这么简单,新接触一款工具,第一是要用起来。第二,就是用的好,只有用的好,才能发挥工具的真正价值。

在用的过程中,又发现了一系列问题,这些问题如果不能解决,就发挥不了一个接口文档的作用,还会增加沟通成本,又有哪些问题呢,一一列举下:

1. 基本使用,如何配置,在类、方法、参数上如何加注解,怎样加注解更好?
2. 接口采用了RESTFul风格,路径上的参数和实体中的参数重合了怎么办?
3. 这个接口文档仅仅是接口文档吗?希望能担当测试大任,这样就不用来回切换工具了,真的能如此吗?
4. 2.9.2版本的风格太low怎么办?

SpringBoot2.1.4.RELEASE整合swagger框架,下面一步一步来。

第一步,在pom文件中,引入swagger框架,刚开始使用的是2.2.2版本
<!-- swagger RESTful API 文档 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.2.2</version>
        </dependency>
        <!-- swagger ui  -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.2.2</version>
        </dependency>   
第二步,添加配置文件
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * 在线文档生成,参考网址:https://hacpai.com/article/1534735914420
 * https://blog.csdn.net/sanyaoxu_2/article/details/80555328
 * @author 程就人生
 * @date 2019年5月29日
 */
@Configuration
@EnableSwagger2
public class Swagger2 {

    @Bean
    public Docket createRestApi() {
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("服务接口文档范例")
                .description("服务接口文档,严格遵循RESTful API设计规范。")
                .contact("程就人生")
                .version("1.0")
                .build();

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo)
                .select()
                 //以扫描包的方式
                .apis(RequestHandlerSelectors.basePackage("com.example.demo.controller"))
                .paths(PathSelectors.any())
                .build();
    }

}

说明:在配置文件中,已经设置了以扫描包的方式来生成接口文档。
这时启动项目,输入地址localhost:8080/swagger-ui.html,可以看到已经生成的接口文档,界面还是相当漂亮的,这只是加了配置,还未加注解的。


图-1

图-2

图-3

图-4

图-5
第三步,接下来,先了解一下,swagger里面都有哪些注解吧;如果一个注解不加,都是英文的,未免太粗糙,写接口的人能看得懂,对接的未必能看懂,把文档进一步细化一下;
@Api(value=”类的中文说明”, description=”类名称”),类注解,是加在类上的,当然api里面还有其他的参数,暂时没有用到,先忽略,2.9版本只认识tags不认识value
@ApiOperation(value=”方法名称说明”,tags=”方法描述”) 方法上的注解
@ApiImplicitParams({

@ApiImplicitParam(paramType="path", name = "userUid", value = "某个商友信息的uid", required = true, dataType = "String")
}) 方法上需要传递很多参数,可以使用这个进行配置,name必须和方法上的参数保持一致,否则会出现两条

@ApiParam(value=”参数中文名称”,required=true)也可以用这个注解直接在参数的前面增加注解,但是个人更建议使用上一个注解
@ApiIgnore 某个参数需要忽略时,可以使用这个注解
@ApiModel 加在实体类上
@ApiModelProperty(value=”参数中文名称”,required=true)加在实体中的属性上,给属性一个中文描述,让对接人员看得懂;
第四步,实际应用
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.entity.User;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@Api(value="swagger测试", description="TestController")
@RequestMapping("/user")
@RestController
public class TestController {

    @ApiOperation(value="获取用户",notes="根据id获取用户")
    @ApiImplicitParams({
        @ApiImplicitParam(paramType="path", name = "id", value = "用户id", required = true, dataType = "Integer")
    })
    @GetMapping("/{id}")
    public Object get(@PathVariable Integer id){
        User user = new User();
        user.setUsername("程就人生");
        user.setId(id);
        return user;
    }
    
    @ApiOperation(value="新增用户") 
    @PostMapping
    public Object add(User user){
        
        return user;
    }
    
    @ApiOperation(value="修改用户",notes="根据id修改用户")    
    @ApiImplicitParams({
        @ApiImplicitParam(paramType="path", name = "id", value = "用户id", required = true, dataType = "Integer")
    })
    @PutMapping("/{id}")
    public Object update(@PathVariable Integer id, User user){
        
        return user;
    }
    
    @ApiOperation(value="删除用户",notes="根据id删除用户")    
    @ApiImplicitParams({
        @ApiImplicitParam(paramType="path", name = "id", value = "用户id", required = true, dataType = "Integer")
    })
    @DeleteMapping("/{id}")
    public Object delete(@PathVariable Integer id){
        
        return id;
    }   
}
第五步,查看效果,此时,每个方法上都有了说明,方法中的参数也有了说明,有的接口还可以进行测试;
图-6

图-7

但是实体类接收不到参数的呀,而且还不知道实体类中有哪些属性,需要手动输入,这个太太不友好了吧,不能算一个清晰的对接文档,这个有没有办法解决呢??

听说还有高级第一点的版本,那就试试吧!

第一步,把pom中的引入文件换成2.9.2版本的
<!-- swagger RESTful API 文档 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- swagger ui  -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
第二步,迫不及待的看看效果如何

图-8

图-9

只想说,天哪,界面也太不友好了吧?但是有一点比较好,实体类里面的属性都是可见的,咦,能不能把功能留下,把界面样式换成2.2.2的呢,试一试吧,一试,效果还不错哟!
结果,配置文件就变成了这样的:

<!-- swagger RESTful API 文档 -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!-- swagger ui  -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.2.2</version>
        </dependency>   

效果变成这样的,还是很不错的哟,看一看能不能用来测试,居然可以测试,四个接口都能够测试。


图-10

图-11

总结:

  1. 在使用PUT或其他方法的时候,路径上面传递了一个id,/{id}这种的,后面又有实体类的,这时,这个id参数的paramType必须为path,不可以为query,如果写成了query,在接受参数的时候,就会报String转integer的错误,这是因为使用query,把参数拼接在问号后面了,实体里面又有一个,提交给后台的就有两个了,paramType为path在提交后台时,框架默认就会把id封装到实体里面,不会报错了。
  2. 方法上的某个参数需要忽略时,可以使用@ApiIgnore进行注解,这样在文档里就不会展示了。
  3. 对于实体里面的属性,想添加描述的,可以在属性上增加@ApiModelProperty(value=”参数中文名称”,required=true),来对参数进行中文描述,还可以添加hidden=true,来设置某个属性不展示。
  4. 在2.9.2版本中,@Api不识别value,可以把value改成tags
  5. 如果把方法中的notes改成tags,那么每个方法都会单独展示,而不会显示在类的下面。
  6. 如果想加个header头,可以在@ApiImplicitParams注解里面,增加一行@ApiImplicitParam(paramType="header", name = "cookie", value = "cookie", required = true, dataType = "String"),设置paramType为header即可。
  7. 除了使用@ApiImplicitParam注解方法上的参数,还可以使用@ApiParam(value=”参数中文名称”,required=true)直接加在参数前面。
@ApiOperation(value="修改用户名",notes="根据id修改用户名")
    @PutMapping
    public Object updateUsername(@ApiParam(value="用户id",required=true)@RequestParam Integer id, @ApiParam(value="用户名称",required=true)@RequestParam String username, @ApiIgnore User user){
        
        return user;
    }
图-12

图-13
  1. 别用debug模式,否则会很慢很慢;
  2. 可能在某些浏览器下,不能正常展示;
  3. 不知道屏幕前的您还有什么高见,欢迎点评!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352