收藏springbootSpring Boot全家桶

Spring Boot之整合Swagger

2020-07-17  本文已影响0人  狄仁杰666

前言

经过之前文章的学习,我们学会了:

有了这些基础知识,可以说,我们已经拥有Spring Boot项目开发的入门基础了。

现实场景中,我们往往需要知道API的文档,才能用于测试、交付等,土一点的做法是开发人员编写API文档,如Wiki、Word、其他在线文档等,实际上,有很多开源资源帮我们从技术上实现了API规格的文档化,而Swagger是Spring Boot生态中的佼佼者,也是官方推荐的。

Swagger的主要优点有:

  1. 免费开源,并且官网提供了丰富的工具和文档介绍;
  2. 通过代码添加注解,自动生成API文档;
  3. 提供在线API文档,API文档随API变化而自动同步更新;
  4. 可开启UI界面,界面美观、清晰;
  5. UI界面支持在线测试API;
  6. 支持多种语言(Java,PHP...);
  7. 采用OpenAPI 规范;
    (OpenAPI定义了RESTful APIs的编写规范。规范中指定了一套模式/模型。这套规范是Swagger为各种编程语言编写的服务提供接口文档奠定了基础。)
  8. ...

那么,我们今天就一起来学习:

Spring Boot中通过Swagger来做API文档。

本文使用的项目代码,是基于上一篇文章使用的Spring Boot项目:
Spring Boot数据库交互之Mybatis

主要步骤

  1. 添加依赖;
  2. 创建config包;
  3. 创建配置类;
  4. 编写配置类;
  5. 修饰Controller;
  6. 修饰项目启动类;
  7. 启动项目、使用Swagger;

1.添加依赖;

//在pom.xml文件中的dependencies节点内添加以下内容:
<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>

2.创建config包;

项目根目录下创建config包:

config包

3.创建配置类;

配置类

4.编写配置类;

1. 编写Swagger配置类;

该步骤的意义:

配置Swagger要扫描API的Controller位置、要显示的API path的样式、初始化的Swagger页面的一些基础信息(见apiInfo()方法);

//生成指定包下的所有API接口信息
RequestHandlerSelectors.basePackage("com.mycompany.sample.controller")
//生成所有API接口
RequestHandlerSelectors.any()
//所有API接口都不生成
RequestHandlerSelectors.none()
//只生成被@Api 这个注解注解过的类接口
RequestHandlerSelectors.withClassAnnotation(Api.class)
//只生成被@ApiOperation 这个注解注解过的API接口
RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)
//所有API均允许生成
PathSelectors.any()
//所有API均不允许生成
PathSelectors.none()
//正则表达式匹配,匹配上则允许生成,如包含getLead的API:
PathSelectors.regex("^(?!getLead).*$")
//只扫描指定的路径下的请求,如只想扫描getLead API路径下的:
//getLead为API path的一部分
PathSelectors.ant("/getLead/**")

代码如下:

package com.mycompany.sample.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;

/**
 * @author : dylanz
 * @since : 07/17/2020
 **/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api() {//名字不限
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(true)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.mycompany.sample.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {//名字不限
        Contact contact = new Contact("Dylan Zhang", "https://www.jianshu.com/u/56578a39a99a", "997604787@qq.com");
        return new ApiInfoBuilder()
                .title("Lead API")
                .contact(contact)
                .description("Lead related operations")
                .termsOfServiceUrl("http://127.0.0.1:8080/getLead/10130546")
                .version("1.0")
                .build();
    }
}

enable设置为:.enable(false),之后访问Swagger UI时就会如下:

关闭Swagger UI

2. 编写WebMvcConfig配置类;

该步骤的意义:覆盖、重写项目配置的(如有)、默认的静态资源路径,这样才能读取到Swagger jar包内的静态文件(html、css文件等);

package com.mycompany.sample.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import javax.annotation.PostConstruct;

/**
 * @author : dylanz
 * @since : 07/17/2020
 **/
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
    @PostConstruct
    public void init() {
        System.out.println("Init in WebMvcConfig...");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/statics/");
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

5.修饰Controller;

package com.mycompany.sample.controller;

import com.mycompany.sample.domain.Lead;
import com.mycompany.sample.service.LeadService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @author : dylanz
 * @since : 07/07/2020
 **/
@RestController
@Api
public class LeadController {
    @Autowired
    private LeadService leadService;

    @GetMapping("/getLead/{leadId}")
    @ResponseBody
    @ApiOperation(value = "get lead by leadId", httpMethod = "GET")
    @ApiImplicitParams(
            {@ApiImplicitParam(name = "leadId", value = "leadId", required = true, paramType = "path", dataType = "Long", example = "10130546")}
    )
    public Lead getLead(@PathVariable(name = "leadId") Long leadId) {
        return leadService.getLeadByLeadId(leadId);
    }
}
1. @Api 注解用来描述该服务的信息,如果不使用则显示类名称;
2. @ApiOperation 注解用于描述接口信息;
3. @ApiParam,@ApiImplicitParam,@ApiImplicitParams 注解用于描述接口的参数;
4. @ApiResponse,@ApiResponses 注解用于描述API返回的信息,不使用会使用默认的、根据接口情况自动生成的描述信息,可在此处自定义错误返回信息,如:

@ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),

5. @ApiVersion 注解用于描述接口的版本信息;

6.修饰项目启动类;

特别注意,只增加使用@EnableSwagger2注解即可;

package com.mycompany.sample;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author : dylanz
 * @since : 07/07/2020
 **/
@SpringBootApplication
@EnableSwagger2
@MapperScan(basePackages = "com.mycompany.sample.dao")
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}

7.启动项目、使用Swagger;

启动项目

Swagger UI HTML站点:http://localhost:8080/swagger-ui.html

HTML站点

页面组成:

1. 标题;
2. API文档JSON入口:http://localhost:8080/v2/api-docs
3. 作者信息;
4. API文档主体;
5. 等。

打开折叠的API列表,我们能看到API的规格:

API规格

以及API使用的实体对象信息:

实体对象信息

我们还可以编辑实体类,修改、细化实体的展示:

package com.mycompany.sample.domain;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * @author : dylanz
 * @since : 07/07/2020
 **/
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@ApiModel
public class Lead implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "leadId", dataType = "Long", name = "id", example = "10130546")
    private Long leadId;
    @ApiModelProperty(value = "email", dataType = "String", name = "email", example = "dylan.zhang@xxxx.com")
    private String email;
}

@ApiModel:生成swagger时扫描的实体注解;
@ApiModelProperty:属性注解,可用于描述实体属性;

修改后,效果如下:

实体注解

还有我特别喜欢的测试API的功能

1. 点击API规格右上角的"Try it out"按钮:

Try it out

2. 点击Execute按钮,测试API:

Execute

3. API测试返回:

API返回

我们可以在页面上修改API参数,如本例为leadId,进行不同参数值的测试(Request Body也支持),而不需要其他测试工具或测试代码,相当方便;

(本例中,我们在controller内@ApiImplicitParam注解中设置了默认值:example = "10130546")

使用Swagger来管理API文档是十分方便、快捷的,界面美观、并且有测试API的功能,对开发人员、测试人员十分友好,满足了绝大多数API文档化的需求。
凡事也要从不同的角度来看待,Swagger强大的背后,也有其一定的局限性:
  1. 仅对于Restful API支持较为友好,其他类型的API支持得不是很好;
  2. 对代码有一定的侵入性;
  3. Swagger与代码需要强绑定;
    (每个API都需要人为添加注解,如果有人偷懒,在API开发时没有加上Swagger对应的注解,那么Swagger UI上是看不到该API的)
  4. ...
综合来看,我还是很喜欢Swagger的,使用简单,功能强大!!!

你Get到了吗?

上一篇下一篇

猜你喜欢

热点阅读