SpringBoot 2.X Kotlin与Swagger2

image

这里有个地方需要注意,在测试WebFlux集成Swagger2的时候存在问题,看了官方文档现在2.9.2还没有集成,所以引入的jar是spring-boot-starter-web,而不是spring-boot-starter-webflux

本章目的

在项目中集成文档及接口测试平台,使用Swagger2可以快速帮助我们编写最新的API接口文档,再也不用担心开会前仍忙于整理各种资料了,间接提升了团队开发的沟通效率。

添加Swagger2依赖

在<code>pom.xml</code>中加入Swagger2的依赖

<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

创建Swagger2配置

package io.intodream.kotlin04.config

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.service.Contact
import springfox.documentation.spi.DocumentationType
import springfox.documentation.spring.web.plugins.Docket
import springfox.documentation.swagger2.annotations.EnableSwagger2

/**
 * @description
 * 构建一个Swagger2配置文件
 * @author Jwenk
 * @copyright intoDream.io 筑梦科技
 * @email xmsjgzs@163.com
 * @date 2019-03-31,21:55
 */
@Configuration
@EnableSwagger2
class Swagger2Config {

    @Bean
    fun createRestApi(): Docket {
        return Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build()
    }

    private fun apiInfo(): ApiInfo {
        return ApiInfoBuilder()
                .title("Spring Boot2.X Kotlin 中使用Swagger2构建RESTFul APIs")
                .description("更多SpringBoot2.X Kotlin 文章请关注:惜鱼博客")
                .termsOfServiceUrl("https://www.intodream.io")
                .contact(Contact("惜鱼", "https://www.tisnz.com", "xmsjgzs@163.com"))
                .version("1.0.0")
                .build()
    }
}

如上代码所示,通过<code>@Configuration</code>注解,让Spring来加载该类配置。再通过<code>@EnableSwagger2</code>注解来启用Swagger2。

再通过createRestApi函数创建Docket的Bean之后,apiInfo()用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。select()函数返回一个ApiSelectorBuilder实例用来控制哪些接口暴露给Swagger来展现,本例采用指定扫描的包路径来定义,Swagger会扫描该包下所有Controller定义的API,并产生文档内容(除了被@ApiIgnore指定的请求)。

编写文档内容

在完成上面的配置后,其实Swagger会自动帮我们生成API的文档,但是自动生成的文档显示并不友好,我们通常需要添加一些额外的信息,这时候就需要通过@ApiOperation注解在API上增加说明,通过@ApiImplicitParams@ApiImplicitParam注解来给参数增加说明。

package io.intodream.kotlin04.web

import io.intodream.kotlin04.model.Student
import io.swagger.annotations.Api
import io.swagger.annotations.ApiImplicitParam
import io.swagger.annotations.ApiOperation
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.web.bind.annotation.*
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap

/**
 * @description
 *
 * @author Jwenk
 * @copyright intoDream.io 筑梦科技
 * @email xmsjgzs@163.com
 * @date 2019-03-31,22:07
 */
@Api(value = "学生信息相关接口", tags = ["学生"])
@RestController
@RequestMapping("/api/student")
class StudentController {

    private var repository : ConcurrentMap<String, Student> = ConcurrentHashMap<String, Student>()
    private val logger : Logger = LoggerFactory.getLogger(this.javaClass)

    @ApiOperation(value = "保存一条学生信息")
    @ApiImplicitParam(name = "student", value = "学生详细实体student", required = true, dataType = "Student")
    @PostMapping("/")
    fun save(@RequestBody student: Student): Student? {
        logger.info("请求参数:{}", student)
        return repository.put(student.id, student)
    }

    @ApiOperation(value = "获取学生列表")
    @GetMapping("/list")
    fun listStudent():List<Student> {
        val studentList = ArrayList<Student>(repository.values)
        logger.info("返回数据:{}", studentList)
        return studentList
    }

    @ApiOperation(value = "通过学生编号获取学生详细信息")
    @ApiImplicitParam(name = "studentId", value = "学生编号", required = true, dataType = "String")
    @GetMapping("/info")
    fun studentInfo(@RequestParam studentId: String): Student? {
        val student : Student? = repository.get(studentId)
        logger.info("studentId:{}, 对应的数据:{}", student)
        return student
    }

    @ApiImplicitParam(name = "studentId", value = "学生编号", required = true, dataType = "String")
    @ApiOperation(value = "删除学生信息")
    @DeleteMapping("/")
    fun deleteStudent(@RequestParam studentId: String): String {
        logger.info("删除学生编号:{}", studentId)
        repository.remove(studentId)
        return "success"
    }
}

完成上述代码添加上,启动Spring Boot程序,访问:http://localhost:8080/swagger-ui.html。就能看到前文所展示的RESTful API的页面。我们可以再点开具体的API请求,以POST类型的/api/student/请求为例,可找到上述代码中我们配置的Notes信息以及参数student的描述信息,如下图所示。

image

image

image

API文档访问与调试

在上图请求的页面中,我们看到student的Example Value是个输入框?是的,Swagger除了查看接口功能外,还提供了调试测试功能,我们可以点击上图中右侧的Model Schema(黄色区域:它指明了User的数据结构),此时Example Value中就有了student对象的模板,我们只需要稍适修改,点击下方“Try it out!”按钮,即可完成了一次请求调用!

到此我们集成Swagger2就完成了,大家可以多测试一下看返回结果是否正确,感觉是不是写接口文档方便了很多呢。

推荐阅读更多精彩内容