一、Swagger简介

  在日常的工作中,我们往往需要给前端(WEB端、IOS、Android)或者第三方提供接口,这个时我们就需要提供一份详细的API说明文档。但维护一份详细的文档可不是一件简单的事情。首先,编写一份详细的文档本身就是一件很费时费力的事情,另一方面,由于代码和文档是分离的,所以很容易导致文档和代码的不一致。这篇文章我们就来分享一种API文档维护的方式,即通过Swagger来自动生成Restuful API文档。

  那什么是Swagger?官方的描述如下:

1
2
3
THE WORLD'S MOST POPULAR API TOOLING
Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS),
enabling development across the entire API lifecycle, from design and documentation, to test and deployment.

  这段话首先告诉大家Swagger是世界上最流行的API工具,并且Swagger的目的是支撑整个API生命周期的开发,包括设计、文档以及测试和部署。这篇文章中我们会用到Swagger的文档管理和测试功能。

  对Swagger的作用有了基本的认识后,我们现在来看看怎么使用。

二、Swagger与Spring boot集成

  第一步:引入对应jar包:

1
2
3
4
5
6
7
8
9
10
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.6.0</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.6.0</version>
</dependency>

  pringfox-swagger2包依赖OSA规范文档(OAS本身是一个API规范,用于描述一整套API接口),是一个描述API的json文件,而这个组件的功能就是帮助我们自动生成这个json文件,组件springfox-swagger-ui包是将这个json文件解析出来,用一种更友好的方式呈现出来。

第二步,基本信息配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.springBoot.Test.controller"))
                .paths(PathSelectors.regex("/test/.*"))
                .build();
    }
 
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("SpringBoot测试Restful API")
                .description("SpringBoot API")
                .termsOfServiceUrl("http://127.0.0.1:8080/")
                .contact(new Contact("飞鹰","127.0.0.1","1234567@qq.com"))
                .version("1.0")
                .build();
    }
 
}

  基础的配置是对整个API文档的描述以及一些全局性的配置,对所有接口起作用。这里涉及到两个注解:

  @Configuration是表示这是一个配置类,是JDK自带的注解,前面的文章中也已做过说明。

  @EnableSwagger2的作用是启用Swagger2相关功能。

  在这个配置类里面我么实例化了一个Docket对象,这个对象主要包括三个方面的信息:

    (1)整个API的描述信息,即ApiInfo对象包括的信息,这部分信息会在页面上展示。

    (2)指定生成API文档的包名。

    (3)指定生成API的路径。按路径生成API可支持四种模式,这个可以参考其源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class PathSelectors {
    private PathSelectors() {
        throw new UnsupportedOperationException();
    }
 
    public static Predicate<String> any() {
        return Predicates.alwaysTrue();
    }
 
    public static Predicate<String> none() {
        return Predicates.alwaysFalse();
    }
 
    public static Predicate<String> regex(final String pathRegex) {
        return new Predicate<String>() {
            public boolean apply(String input) {
                return input.matches(pathRegex);
            }
        };
    }
 
    public static Predicate<String> ant(final String antPattern) {
        return new Predicate<String>() {
            public boolean apply(String input) {
                AntPathMatcher matcher = new AntPathMatcher();
                return matcher.match(antPattern, input);
            }
        };
    }
}

  从源码可以看出,Swagger总共支持任何路径都生成、任何路径都不生成以及正则匹配和ant 模式匹配四种方式。大家可能比较熟悉的是前三种,最后一种ant匹配,如果不熟悉ant的话就直接忽略吧,前三种应该足够大家在日常工作中使用了。

  有了上面的配置我们就可以看到效果了,在"com.SpringBoot.Test.Controller"包下面有一个"HelloController"这个类,源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@RestController
@RequestMapping("/test")
public class HelloController { @RequestMapping(value = "/hello", method = GET, produces = "application/json")
public User getHello(@RequestParam(value="name") String name){
User user = new User();
user.setName(name);
return user;
} @RequestMapping(value = "/hello", method = POST, produces = "application/json")
public User postHello(@RequestBody User user){
return user;
} @RequestMapping(value = "/hello", method = PUT, produces = "application/json")
public User putHello(@RequestBody User user){
return user;
} @RequestMapping(value = "/hello", method = DELETE, produces = "application/json")
public User deleteHello(@RequestParam(value="name") String name){
User user = new User();
user.setName(name);
return user;
}
}

  启动Spring boot,然后访问:http://127.0.0.1:8080/swagger-ui.html即可看到如下结果:

  我们还可以点进去看一下每一个具体的接口,我们这里以“get hello”这个接口为例:

  可以看到,Swagger为每一个接口都生成了返回结果和请求参数的示例,并且能直接通过下面的"try it out"进行接口访问,方面大家对接口进行测试。整体上感觉Swagger还是很强大的,配置也比较简单。

三、Swagger API详细配置

  不过大家看到这里肯定会有点疑问:

    第一个问题:这个返回结果和请求参数都没有文字性的描述,这个可不可以配置?

    第二个问题:这个请求参应该是直接根据对象反射出来的结果,但是不是对象的每个属性都是必传的,另外参数的值也不一定满足我们的需求,这个能否配置?

  答案肯定是可以的,现在我们就来解决这两个问题,直接看配置的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.SpringBoot.Test.Controller;

import com.SpringBoot.Test.dto.User;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import static org.springframework.web.bind.annotation.RequestMethod.*; @RestController
@RequestMapping("/test")
public class HelloController { @ApiOperation(value = "getHello方法", notes = "请填写姓名", tags = "Hello",httpMethod = "GET")
@ApiResponses({
@ApiResponse(code=400,message="请求参数没填好"),
@ApiResponse(code=404,message="请求路径没有或页面跳转路径不对"),
@ApiResponse(code=200,message="返回成功"),
})
@RequestMapping(value = "hello/{name}", method = GET, produces = "application/json")
public User getHello(@PathVariable String name){
User user = new User();
user.setName(name);
return user;
} @ApiOperation(value = "postHello方法", notes = "请填写姓名", tags = "Hello",httpMethod = "POST")
@RequestMapping(value = "/hello", method = POST, produces = "application/json")
public User postHello(@RequestBody User user){
return user;
}

@ApiOperation(value = "putHello方法", notes = "请填写姓名", tags = "Hello",httpMethod = "PUT")
@RequestMapping(value = "/hello/{name}", method = PUT, produces = "application/json")
public User putHello(@PathVariable String name){
User user = new User();
user.setName(name);
return user;
} @ApiOperation(value = "deleteHello方法", notes = "请填写姓名", tags = "Hello",httpMethod = "DELETE")
@RequestMapping(value = "/hello/{name}", method = DELETE, produces = "application/json")
public User deleteHello(@PathVariable String name){
User user = new User();
user.setName(name);
return user;
}
}

  我们解释一下代码中几个注解及相关属性的具体作用:

  @ApiOperation,整个接口属性配置:

    value:接口说明,展示在接口列表。

    notes:接口详细说明,展示在接口的详情页。

    tags:接口的标签,相同标签的接口会在一个标签页下展示。

    httpMethod:支持的HTTP的方法。

  @ApiImplicitParams,@ApiImplicitParam的容器,可包含多个@ApiImplicitParam注解

  @ApiImplicitParam,请求参数属性配置:

    name:参数名称

    value:参数说明

    required:是否必须

    dataType:数据类型  

  @ApiResponses,@ApiResponse容器,可以包含多个@ApiResponse注解

  @ApiResponse,返回结果属性配置:

    code:返回结果的编码。

    message:返回结果的说明。

    response:返回结果对应的类。    

  完成以上配置后,我们再看下页面效果:

列表页:

    

  如上图所示,接口均在"Hello"tag下。如下所示是get请求接口的详情信息。

  上面两个图是get请求,点击"try it out"即展示的就是第二张图的情况了,目前这四个请求的参数均为字符串,当请求的参数是对象时就会涉及另外的两个注解:@ApiModel和@ApiModelProperty,先通过代码的方式有个只管的感受,如下图所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.SpringBoot.Test.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; @ApiModel(value="user对象",description="user基本信息")
public class User { @ApiModelProperty(name = "id",value = "userId",required = true,example = "1")
private String id; @ApiModelProperty(name = "name",value = "姓名",required = false,example = "hello")
private String name; @ApiModelProperty(hidden = true)
private String sex; @ApiModelProperty(hidden = true)
private String age; public User(){
} public User(String id,String name){
this.id = id;
this.name = name;
}

    value:类的说明

    description:详细描述

  @ApiModelProperty是对具体每个字段的属性配置:

    name:字段名称

    value:字段的说明

    required:是否必须

    example:示例值

    hidden:是否显示

  完成上面的配置后,我们再来看效果:

  点击Try it out后,我们就可以看到返回的结果:

  操作还是很方便的,相比Junit和postman,通过Swagger来测试会更加便捷,当然,Swagger的测试并不能代替单元测试,不过,在联调的时候还是有非常大的作用的。

PS:在本地测试的过程中感觉@ApiImplicitParams不太好用,因此在本地测试过程中并未使用。

四、总结

  总体上来说,Swagger的配置还是比较简单的,并且Swagger能够自动帮我们生成文档确实为我们节省了不少工作,对后续的维护也提供了很大的帮助。除此之外,Swagger还能根据配置自动为我们生成测试的数据,并且提供对应的HTTP方法,这对我们的自测和联调工作也有不少的帮助,所以我还是推荐大家在日常的开发中去使用Swagger,应该可以帮助大家在一定程度上提高工作效率的。最后,留一个问题给大家思考吧,就是该文档是可以直接通过页面来访问的,那我们总不能把接口直接暴露在生产环境吧,尤其是要对外提供服务的系统,那我们怎么才能在生产环节中关闭这个功能呢?方法有很多,大家可以自己尝试一下。

参考

http://www.cnblogs.com/paddix/p/8204916.html

Spring Boot文档维护:集成Swagger2的更多相关文章

  1. Spring Boot文档

    本文来自于springboot官方文档 地址:https://docs.spring.io/spring-boot/docs/current/reference/html/ Spring Boot参考 ...

  2. 第2章 Spring Boot 文档

    Spring Boot 文档 本节简要介绍了Spring Boot文档,是整个文档的参考指南. 您可以完整阅读本参考指南,或者如果您不感兴趣的话可以跳过该部分. 1. 关于文档 Spring Boot ...

  3. Spring Boot文档阅读

    原因之初 最初习惯百度各种博客教程,然后跟着操作,因为觉得跟着别人走过的路走可以少走很多弯路,省时间.然而,很多博客的内容并不够完整,甚至错误,看多了的博客甚至有千篇一律的感觉.此外,博客毕竟是记载博 ...

  4. Spring Boot 文档

    本节对 Spring Boot 的参考文档做了一个简单概述.本章节对全文的参考手册进行内容上的一些索引. 你可以参考本节,从头到尾依次阅读该文档,也可以跳过不感兴趣的内容. Spring Boot 参 ...

  5. Spring系列(零) Spring Framework 文档中文翻译

    Spring 框架文档(核心篇1和2) Version 5.1.3.RELEASE 最新的, 更新的笔记, 支持的版本和其他主题,独立的发布版本等, 是在Github Wiki 项目维护的. 总览 历 ...

  6. spring接口文档注解:@ApiOperation(转)

    spring接口文档注解:@ApiOperation @ApiOperation不是spring自带的注解是swagger里的 com.wordnik.swagger.annotations.ApiO ...

  7. Spring Boot微服务如何集成fescar解决分布式事务问题?

    什么是fescar? 关于fescar的详细介绍,请参阅fescar wiki. 传统的2PC提交协议,会持有一个全局性的锁,所有局部事务预提交成功后一起提交,或有一个局部事务预提交失败后一起回滚,最 ...

  8. Spring Boot 2.0 快速集成整合消息中间件 Kafka

    欢迎关注个人微信公众号: 小哈学Java, 每日推送 Java 领域干货文章,关注即免费无套路附送 100G 海量学习.面试资源哟!! 个人网站: https://www.exception.site ...

  9. Spring Boot与ActiveMQ的集成

    Spring Boot对JMS(Java Message Service,Java消息服务)也提供了自动配置的支持,其主要支持的JMS实现有ActiveMQ.Artemis等.本节中,将以Active ...

随机推荐

  1. Vue编译提示警告

    There are multiple modules with names that only differ in casing.有多个模块同名仅大小写不同This can lead to unexp ...

  2. django之Session、Cookie

    Session ·Session存在于服务器端 ·Session的设置: request.session['name'] = value ·Session的获取: dic = request.sess ...

  3. js实现颜色渐变

    #grad { background: -webkit-linear-gradient(red, blue); /* Safari 5.1 - 6.0 */ background: -o-linear ...

  4. python int str

    1. int 类型转换 a = "123" b = int(a) b = b+10 print(type(a),a) print(type(b),b) 2. int(num,bas ...

  5. alpha冲刺(4/10)

    前言 队名:旅法师 作业链接 队长博客 燃尽图 会议 会议照片 会议内容 陈晓彬(组长) 今日进展: 召开会议 安排任务 博客撰写 问题困扰: pm和程序猿的交流到底应该怎么样呢,会出现,不做安排的任 ...

  6. sdn的相关学习系列之一mininet的安装

    Ubuntu16.04安装mininet 1.安装git命令 sudo apt-get install git 2.从Github上下载Mininet官网的源码 git clone git://git ...

  7. java-启动和关闭.exe程序

    链接: https://www.cnblogs.com/pengpengzhang/p/8675740.html https://blog.csdn.net/ZHANGHUI3239619/artic ...

  8. DSP2812  启动详解

    百度文库转载 1. 从0X3F FFC0处复位→执行0X3F FC00地址处的初始化引导函数(Initboot) →根据GPIO选择引导模式→确定用户程序入口地址→从入口处开始执行用户程序. 输入外部 ...

  9. Python中的闭包 - Closure

    Python中的闭包不是一个一说就能明白的概念,但是随着你往学习的深入,无论如何你都需要去了解这么一个东西. 闭包的概念 我们尝试从概念上去理解一下闭包. 在一些语言中,在函数中可以(嵌套)定义另一个 ...

  10. MySQL 5.7临时表空间

    MySQL 5.7起,开始采用独立的临时表空间(和独立的undo表空间不是一回事哟),命名ibtmp1文件,初始化12M,且默认无上限. 选项 innodb_temp_data_file_path 可 ...