SpringBoot基础学习之整合Swagger框架(上篇)

前言

小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师。


这个SpringBoot基础学习系列用来记录我学习SpringBoot框架基础知识的全过程 (这个系列是参照B站狂神的SpringBoot最新教程来写的,由于是之前整理的,但当时没有发布出来,所以有些地方可能有错误,希望大家能够及时指正!)

之后我将会尽量以一天一更的速度更新这个系列,还没有学习SpringBoot的小伙伴可以参照我的博客学习一下;当然学习过的小伙伴,也可以顺便跟我一起复习一下基础。最后,希望能够和大家一同进步吧!加油吧!少年们!


由于篇幅较长,所以这里我将其分为了上下两篇博客上篇主要了解Swagger的概念,学习SpringBoot整合Swagger,以及配置Swagger和扫描接口下篇主要学习Swagger配置是否启动 和 设置Swagger文档注释,以及Swagger在线测试等

今天我们来到了SpringBoot基础学习的第九站:整合Swagger框架(上篇)。废话不多说,让我们开始今天的学习内容吧!

9.Swagger的使用

学习目标

  • 了解Swagger的作用和概念
  • 了解前后端分离
  • 在SpringBoot中集成Swagger

9.1 Swagger简介

在介绍Swagger之前,先来了解一下什么是前后端分离?因为Swagger的出现就是为了方便管理前后端分离项目

9.1.1 什么是前后端分离?

到2021年了,“前后端分离”这个名词想必大家都不陌生了,因为目前市场上的很多项目都是前端采用 Vue框架,后端采用SpringBoot框架的设计方案。

这里我简单说一下我对前后端分离的理解,前后端分离从字面上看也就是说前端和后端分离开了,那为什么要分离开嘞?

下面我就从分工合作工作效率还有代码管理三个方面解释一下:

分工合作方面:大家还记得在初学JavaWeb时,被Servlet和JSP支配的恐惧吗?我们很多时候不得不在前端的JSP页面里写一堆Java后端代码;这就意味着,设计过程必须先由后端程序员编写后端的Java代码,然后前端程序员编写前端JSP代码,如果前端想要渲染数据,还要让后端程序员在前端JSP页面写后端代码,先不说这个工作流程麻不麻烦,如果前端程序员想要修改一些功能,还要求着后端程序员来改,我前端程序员还得看你后端程序员脸色是吧,大家都是要面子的是吧,改来改去谁也嫌麻烦,万一后端和前端干起来了,项目经理还得花时间劝架,大伙不仅可能面临加班,而且项目可以又要延期上线!

工作效率方面:在JSP时代,前后端想同时进行是不太可能的事情,往往都是先写Java后端代码,然后再写JSP页面中的前端代码,然后再写JSP页面里的后端代码,这样一来一回的,同时进行是不可能的事情。但如果前后端分离之后,在项目的整体设计方案敲定后,前端和后端只需要提前商量好,大家调用事先设计好的接口,然后接收和发送对应的数据进行处理就完事了,这样前端后端同时进行,不仅有了更多的时间去做前期的需求分析和详细设计,也能有充裕的时间进行系统的测试,保证项目的整体质量,甚至能够提前上线!

代码管理方面:在前端的JSP页面是写一堆后端Java代码,不仅后端程序员觉得别扭,前端程序员也觉得别扭 (前端程序员如果懂都后端还行,不懂后端代码,估计是一脸懵逼吧),而且这也违反了软件设计中的“高内聚,低耦合”原则,前端后端代码糅杂在一起,这耦合度确实挺高的,后期维护起来,那得后端程序员得和前端程序员一起上,不仅浪费时间,还浪费人力。

接下来跟大家聊一下后端时代和前后端分离时代的一些主要区别

9.1.2 后端时代和前后端分离时代区别

后端时代

刚开始前端只用管理静态页面,也就是html页面,然后交给后端进行处理;后来出现了模板引擎,也就是JSP (Java Server Page,即Java服务器页面),这时候后端是主力 (哈哈,也就是说,那个时候后端程序员要比前端程序员工资高)

前后端分离时代

  • 后端:后端主要分为控制层(Controller)、服务层(Service)、数据持久/访问层(Dao)【由后端团队开发】

  • 前端:前端控制层,视图层【由前端团队开发】

    也就是伪造后端数据:使用json格式保存数据,不需要后端发送数据,前端工程能够独立运行

  • 前后端如何交互?使用提前定义好的API数据接口

  • 前后端工程相对独立,达到松耦合的目的

  • 前后端可以部署在不同的服务器上

但同时也就产生了一个问题

  • 前后端的集成联调问题,也就是说前端开发人员和后端开发人员无法做到“及时协商”,可能前端只是增加一个简单的功能,但是却需要后端编写大量的代码

  • 唯一的解决方式就是“及时协商,尽早解决”,否则耽误项目对的工期和上线时间,甚至项目组成员被开除,造成内部矛盾被激化,从而导致问题集中式爆发,这不是我们想看的的结果。

具体解决方案

  • 首先制定schema【计划提纲】,实时更新最新的API接口,降低前后端集成的风险
  • 早些年很多公司采用制定Word计划文档的方式,但这种方式效率低,同步性差
  • 进入前后端分离分离时代后:前端想要测试后端接口,可以使用postman测试工具;而后端提供接口,并且需要实时更新最新的消息及改动!

9.1.3 Swagger简单介绍

1.什么是Swagger?

  • Swagger号称世界上最流行的API框架;
  • 它支持RestFul风格的API文档的在线自动生成工具,可以实现API文档与API定义同步更新;
  • 可以直接运行,实现在线测试API接口;
  • 同时支持多种主流开发语言 (例如Java和PHP等)

Swagger官网的介绍如下

Swagger是面向所有人的API 开发,使用 Swagger 开源和专业工具集为用户、团队和企业简化 API 开发。

Swagger官网地址:https://swagger.io/

2.如何在项目中使用Swagger?

在项目中使用Swagger时,需要用到SpringFox

  • Swagger2
  • Swagger UI
2-1 什么是SpringFox?

SpringFox是一个开源的API Doc的框架, 它的前身是swagger-springmvc,可以将我们的Controller中的方法以文档的形式展现。

2-2 SpringFox能做什么?
  • 使前后端更加解耦,保证API文档的实时同步:前后端的对接通常是API形式,而后端开发人员在开发过程中,提供的API和描述文档却是难以同步的,往往是开发代码完成了,但文档描述并不及时,甚至会遗忘这一环节,导致前端调用后端API时经常发生错误。SpringFox应运而生,使前端和后端有效分离,同时保证API与文档的实时更新;
  • 生成的接口文档直观可视:使用SpringFox不仅可以生成直观可视的接口文档,同时也帮助后端开发人员脱离了写接口文档的痛苦,还避免了不厌其烦的解说各个接口需要的参数和返回结果;
  • 支持在线测试:SpringFox可以支持在线测试,可以实时检查参数和返回值

9.2 SpringBoot集成Swagger

9.2.1 搭建项目基本环境

1.创建Spring Initialzr项目

SpringBoot基础学习之整合Swagger框架(上篇)

2.设置项目基本信息

SpringBoot基础学习之整合Swagger框架(上篇)

3.勾选项目相关资源依赖

SpringBoot基础学习之整合Swagger框架(上篇)

4.选择项目存放位置

SpringBoot基础学习之整合Swagger框架(上篇)

9.2.2 导入相关资源依赖

1.查看pom.xml文件基本信息

  • 由于创建项目时我们勾选了Spring Web资源依赖,所以在pom.xml配置文件中自动生成了springboot-webspringboot-test的相关资源依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.kuang</groupId>
    <artifactId>swagger</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>swagger</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!-- springboot-web的资源依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- springboot-test的资源依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.添加springfox-swagger资源依赖

  • 由于springboot并没有为我们提供swagger的资源依赖,所以我们这里选择手动添加资源依赖,springboot整合springfox-swagger的资源依赖如下:
<!-- springfox-swagger2的资源依赖 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>

3.查看资源依赖是否导入成功

SpringBoot基础学习之整合Swagger框架(上篇)

4.导入资源后的项目基本结构

SpringBoot基础学习之整合Swagger框架(上篇)

9.2.3 项目页面访问测试

1.项目结构信息

  • src源文件下的com.kuang.swagger包下创建一个controller包,创建HelloController前端控制器类

SpringBoot基础学习之整合Swagger框架(上篇)

2.编写HelloController控制器代码

package com.kuang.swagger.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName HelloController
 * @Description Hello前端控制器
 * @Author 狂奔de蜗牛rz
 * @Date 2021/10/1
 */

// 使用@RestController注解, 实现Controller接口, 使方法返回字符串
@RestController
public class HelloController {

    // 使用@RequestMapping注解, 设置请求映射路径, 请求方式为get类型
    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }

}

3.访问页面测试结果

SpringBoot基础学习之整合Swagger框架(上篇)

结果访问成功,页面显示“hello”字符串!

9.2.4 解决无法swagger-ui.html页面问题

在后续访问swagger-ui.html页面时,遇到了无法访问页面的问题,解决方案如下:

1.Swagger版本降级

  • 降级到2.9.2版本
<!-- springfox-swagger2的资源依赖 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>

2.修改artifactId和使用@EnableOpenApi注解

artifactId修改为springfox-boot-starter, 并且在启动类前加上@EnableOpenApi注解

2-1 修改后的pom.xml配置文件
<!-- springfox-swagger2的资源依赖 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-boot-starter</artifactId>
    <version>3.0.0</version>
</dependency>
2-2 修改SwaggerApplication启动类
package com.kuang.swagger;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import springfox.documentation.oas.annotations.EnableOpenApi;

@SpringBootApplication
// 使用Swagger2的3.0.0版本时, 需加上该注解
@EnableOpenApi
public class SwaggerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SwaggerApplication.class, args);
    }

}

3.再次访问swagger-ui.html页面

注意Swagger2的2.9.2版本需要访问swagger-ui.html页面,而3.0.0版本需要访问swagger-ui/index.html页面!

SpringBoot基础学习之整合Swagger框架(上篇)

结果访问swagger-ui页面成功!

9.3 SpringBoot配置Swagger

9.3.1 Swagger配置类的Docket类源码浅析

1.Docket类源码浅析

package springfox.documentation.spring.web.plugins;

// Docket类, 其实现了DocumentationPlugin(文档插件)接口
public class Docket implements DocumentationPlugin {
    
    // 使用公开的静态终极修饰的默认组名
    public static final String DEFAULT_GROUP_NAME = "default";
    private final DocumentationType documentationType;
    private final List<SecurityContext> securityContexts = new ArrayList();
    private final Map<RequestMethod, List<ResponseMessage>> responseMessages = new HashMap();
    private final Map<HttpMethod, List<Response>> responses = new HashMap();
    private final List<Parameter> globalOperationParameters = new ArrayList();
    private final List<Function<TypeResolver, AlternateTypeRule>> ruleBuilders = new ArrayList();
    private final Set<Class> ignorableParameterTypes = new HashSet();
    private final Set<String> protocols = new HashSet();
    private final Set<String> produces = new LinkedHashSet();
    private final Set<String> consumes = new LinkedHashSet();
    private final Set<ResolvedType> additionalModels = new HashSet();
    private final Set<Tag> tags = new HashSet();
    private final List<Server> servers = new ArrayList();
    private PathProvider pathProvider;
    private List<SecurityScheme> securitySchemes;
    private Comparator<ApiListingReference> apiListingReferenceOrdering;
    private Comparator<ApiDescription> apiDescriptionOrdering;
    private Comparator<Operation> operationOrdering;
    private ApiInfo apiInfo;
    private String groupName;
    private boolean enabled;
    private GenericTypeNamingStrategy genericsNamingStrategy;
    private boolean applyDefaultResponseMessages;
    private String host;
    private Optional<String> pathMapping;
    private ApiSelector apiSelector;
    private boolean enableUrlTemplating;
    private final List<VendorExtension> vendorExtensions;
    private final List<RequestParameter> globalRequestParameters;
    
    /** 
     * Docket的有参构造函数
     * @param documentationType 文档类型
     */
    public Docket(DocumentationType documentationType) {
        // 设置API信息为默认值
        this.apiInfo = ApiInfo.DEFAULT;
        // 设置默认组名为default
        this.groupName = "default";
        // 设置是否生效, 设置为true(表示生效)
        this.enabled = true;
	    // 设置生成名字策略, 其值为创建一个默认生成类型策略类		
        this.genericsNamingStrategy = new DefaultGenericTypeNamingStrategy();
        // 设置应用默认响应信息
        this.applyDefaultResponseMessages = true;
        // 设置主机名, 默认为空
        this.host = "";
        // 设置映射路径
        this.pathMapping = Optional.empty();
        // 设置api选择器
        this.apiSelector = ApiSelector.DEFAULT;
        // 设置是否开启url模板
        this.enableUrlTemplating = false;
        // 设置扩展器
        this.vendorExtensions = new ArrayList();
        // 设置全局请求参数
        this.globalRequestParameters = new ArrayList();
        // 设置文档类型
        this.documentationType = documentationType;
    }
    
    // ...(省略后面部分代码)...

}

2.DocumentationType类源码浅析

package springfox.documentation.spi;

// 文档类型子类, 实现简单插件元数据父类
public class DocumentationType extends SimplePluginMetadata {
    // 文档类型SWAGGER_12, 设置文档类型构造函数的参数为swagger和1.2
    public static final DocumentationType SWAGGER_12 = new DocumentationType("swagger", "1.2");
    // 文档类型SWAGGER_2, 设置文档类型构造函数的参数为swagger和2.0
    public static final DocumentationType SWAGGER_2 = new DocumentationType("swagger", "2.0");
    // 文档类型OSA_30, 设置文档类型构造函数的参数为openApi和3.0
    public static final DocumentationType OAS_30 = new DocumentationType("openApi", "3.0");
    /** @deprecated */
    @Deprecated
    // 文档类型为SPRING_WEB, 设置文档类型构造函数的参数为spring-web和5.2
    public static final DocumentationType SPRING_WEB = new DocumentationType("spring-web", "5.2");
    // 媒介类型
    private final MediaType mediaType;
    
    // 文档类型有参构造函数1(三个参数)
    public DocumentationType(String name, String version, MediaType mediaType) {
        super(name, version);
        this.mediaType = mediaType;
    }
    
    // 档类型有参构造函数2(两个参数)
    public DocumentationType(String name, String version) {
        this(name, version, MediaType.APPLICATION_JSON);
    }
    
    // 获取媒介类型
    public MediaType getMediaType() {
        return this.mediaType;
    }
    // equals方法
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        } else if (!(o instanceof DocumentationType)) {
            return false;
        } else if (!super.equals(o)) {
            return false;
        } else {
            DocumentationType that = (DocumentationType)o;
            return super.equals(that) && this.mediaType.equals(that.mediaType);
        }
    }
    
    // hashCode方法
    public int hashCode() {
        int result = super.hashCode();
        result = 31 * result + this.mediaType.hashCode();
        return result;
    }
}

3.ApiInfo类源码浅析

package springfox.documentation.service;

// ApiInfo类
public class ApiInfo {
    
    // 默认的合并多个字符串
    public static final Contact DEFAULT_CONTACT = new Contact("", "", "");
    public static final ApiInfo DEFAULT; // Api的默认信息
    private final String version; // 版本
    private final String title; // 标题
    private final String description; // 描述
    private final String termsOfServiceUrl; // 服务条件url
    private final String license; // 许可证
    private final String licenseUrl; // 许可证url
    private final Contact contact; // 域名简介
    private final List<VendorExtension> vendorExtensions; // 扩展

    
    @Deprecated // 使用@Deprecated注解, 表示已弃用
    public ApiInfo(String title, String description, String version, String termsOfServiceUrl, String contactName, String license, String licenseUrl) {
        this(title, description, version, termsOfServiceUrl, new Contact(contactName, "", ""), license, licenseUrl, new ArrayList());
    }

    // Api信息的有参构造函数
    public ApiInfo(String title, String description, String version, String termsOfServiceUrl, Contact contact, String license, String licenseUrl, Collection<VendorExtension> vendorExtensions) {
        this.title = title;
        this.description = description;
        this.version = version;
        this.termsOfServiceUrl = termsOfServiceUrl;
        this.contact = contact;
        this.license = license;
        this.licenseUrl = licenseUrl;
        this.vendorExtensions = new ArrayList(vendorExtensions);
    }
 
    /**
     * 生成的get方法
     */
    // 获取标题
    public String getTitle() {
        return this.title;
    }

    // 获取描述
    public String getDescription() {
        return this.description;
    }

    // 获取服务条件url
    public String getTermsOfServiceUrl() {
        return this.termsOfServiceUrl;
    }

    // 获取域名
    public Contact getContact() {
        return this.contact;
    }

    // 获取许可证
    public String getLicense() {
        return this.license;
    }

    // 获取许可证url
    public String getLicenseUrl() {
        return this.licenseUrl;
    }

    // 获取版本
    public String getVersion() {
        return this.version;
    }

    // 获取扩展
    public List<VendorExtension> getVendorExtensions() {
        return this.vendorExtensions;
    }

    // 静态代码块
    static {
        // api信息的默认值为创建一个ApiInfo类, 设置其构造函数的主要参数信息
        DEFAULT = new ApiInfo("Api Documentation", "Api Documentation", "1.0", "urn:tos", DEFAULT_CONTACT, "Apache 2.0", "http://www.apache.org/licenses/LICENSE-2.0", new ArrayList());
    }
    
}

9.3.2 编写Swagger配置类信息

1.Swagger配置类实现代码

package com.kuang.swagger.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;

import java.util.ArrayList;

/**
 * @ClassName SwaggerConfig
 * @Description Swagger配置类
 * @Author 狂奔de蜗牛rz
 * @Date 2021/10/1
 */

// 将SwaggerConfig类注册为配置类
@Configuration
// 开启Swagger2的支持
@EnableSwagger2
public class SwaggerConfig {

    // 使用@Bean注解, 将docket注册为IOC容器中的Bean节点
    @Bean
    public Docket docket() {
        // 返回值为新建一个Docket类, 其构造函数的参数为DocumentationType.SWAGGER_2(表示文档类型为Swagger2)
        return new Docket(DocumentationType.SWAGGER_2)
                // 将apiInfo设置为自定义的
                .apiInfo(myApiInfo());
    }

    // 配置Swagger信息apiInfo
    private ApiInfo myApiInfo() {

        // 作者的名字, url和邮箱地址
        Contact contact = new Contact("狂奔de蜗牛rz","https://mp.csdn.net/?spm=1000.2115.3001.4503","1441505359@qq.com");
        // 返回值为创建一个新的ApiInfo类, 设置基本信息
        return new ApiInfo("自定义SwaggerApi文档",
                            "乘风破浪会有时, 直挂云帆济沧海",
                            "V1.0",
                            "http://localhost:8080/hello",
                             contact,
                            "Apache 2.0",
                            "http://www.apache.org/licenses/LICENSE-2.0",
                            new ArrayList<>());
    }

}

2.访问swagger-ui页面测试

  • 访问默认的swagger-ui页面,查看文档主要信息:

    可以发现,该API文档主要包括两个前端控制器,分别是基本的错误控制器hello控制器

SpringBoot基础学习之整合Swagger框架(上篇)

  • 访问基本的错误前端控制器接口,查看相关方法信息:

经过观察可以发现,该接口的方法主要包括了RestFul风格的各类请求方式:

首先是常见的四种请求方式:POST(对应添加操作)、DELETE(对应删除操作)、PUT(对应修改操作)、GET(对应查询操作),也就是常用的增删改查操作;还有三个不太常用的:HEAD(获取资源的元数据)、PATCH(对应修改操作,只能提供资源的部分属性)、OPTIONS(对应查询操作,获取指定的属性信息)

SpringBoot基础学习之整合Swagger框架(上篇)

  • 访问基本的hello前端控制器接口,查看相关方法信息:

    主要方法类型跟基本错误控制器相同,这里就不再进行说明了

SpringBoot基础学习之整合Swagger框架(上篇)

知识扩展

那你是否想过:为什么我们可以在端口号后面加上swaggee-ui/index.html,就可以访问到Swagger的API文档页面了呢?

  • 查看项目左侧的外部库,找到springfox-swagger-ui,点击MATA-INF下的resources包,你会发现有一个index.html页面,这就是我们所访问的那个Swagger的API文档页面!

SpringBoot基础学习之整合Swagger框架(上篇)

9.4 Swagger配置扫描接口

9.4.1 查看RequestHandlerSelectors类源码

package springfox.documentation.builders;

// RequestHandlerSelectors(请求处理器选择器)类
public class RequestHandlerSelectors {
    // 请求处理器选择器类的无参构造函数
    private RequestHandlerSelectors() {
        //抛出不支持操作异常
        throw new UnsupportedOperationException();
    }
    
    // 扫描任何包路径
    public static Predicate<RequestHandler> any() {
        //使用lambda表达式写法, 其主要形式为()->{} 方法作为参数
        return (each) -> {
            return true;
        };
    }
    
    // 不扫描任何包路径
    public static Predicate<RequestHandler> none() {
        return (each) -> {
            return false;
        };
    }
    
    // 扫描方法的注解(参数为注解的反射对象)
    public static Predicate<RequestHandler> withMethodAnnotation(final Class<? extends Annotation> annotation) {
        return (input) -> {
            return input.isAnnotatedWith(annotation);
        };
    }
    
    // 扫描类的注解
    public static Predicate<RequestHandler> withClassAnnotation(final Class<? extends Annotation> annotation) {
        return (input) -> {
            return (Boolean)declaringClass(input).map(annotationPresent(annotation)).orElse(false);
        };
    }

    // 扫描预先的注解
    private static Function<Class<?>, Boolean> annotationPresent(final Class<? extends Annotation> annotation) {
        return (input) -> {
            return input.isAnnotationPresent(annotation);
        };
    }

    // 控制器包
    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
        return (input) -> {
            return ClassUtils.getPackageName(input).startsWith(basePackage);
        };
    }

    // 基本包
    public static Predicate<RequestHandler> basePackage(String basePackage) {
        return (input) -> {
            return (Boolean)declaringClass(input).map(handlerPackage(basePackage)).orElse(true);
        };
    }

    // 声明类
    private static Optional<Class<?>> declaringClass(RequestHandler input) {
        return Optional.ofNullable(input.declaringClass());
    }
    
}

9.4.2 编写Swagger配置类和页面访问测试

1.只设置扫描指定的基本包路径

  • 编写Swagger配置类实现代码
package com.kuang.swagger.config;

/**
 * @ClassName SwaggerConfig
 * @Description Swagger配置类
 * @Author 狂奔de蜗牛rz
 * @Date 2021/10/1
 */

// 将SwaggerConfig类注册为配置类
@Configuration
// 开启Swagger2的支持
@EnableSwagger2
public class SwaggerConfig {

    // 使用@Bean注解, 将docket注册为IOC容器中的Bean节点
    @Bean
    public Docket docket() {
        // 返回值为新建一个Docket类, 其构造函数的参数为DocumentationType.SWAGGER_2(表示文档类型为Swagger2)
        return new Docket(DocumentationType.SWAGGER_2)
                // 将apiInfo设置为自定义的
                .apiInfo(myApiInfo())
                // Api的选择器
                .select()
                // 设置api信息, 传入参数为RequestHandlerSelectors(请求控制器选择器), 配置basePackage信息(扫描指定的基本包路径)
                .apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
                .build();
    }

    // 配置Swagger信息apiInfo
    private ApiInfo myApiInfo() {

        // 作者的名字, url和邮箱地址
        Contact contact = new Contact("狂奔de蜗牛rz","https://mp.csdn.net/?spm=1000.2115.3001.4503","1441505359@qq.com");
        // 返回值为创建一个新的ApiInfo类, 设置基本信息
        return new ApiInfo("自定义SwaggerApi文档",
                            "乘风破浪会有时, 直挂云帆济沧海",
                            "V1.0",
                            "http://localhost:8080/hello",
                             contact,
                            "Apache 2.0",
                            "http://www.apache.org/licenses/LICENSE-2.0",
                            new ArrayList<>());
    }

}
  • 访问swagger-ui页面API文档信息

SpringBoot基础学习之整合Swagger框架(上篇)

2.设置扫描指定包路径和过滤路径

  • 编写Swagger配置类实现代码
package com.kuang.swagger.config;

/**
 * @ClassName SwaggerConfig
 * @Description Swagger配置类
 * @Author 狂奔de蜗牛rz
 * @Date 2021/10/1
 */

// 将SwaggerConfig类注册为配置类
@Configuration
// 开启Swagger2的支持
@EnableSwagger2
public class SwaggerConfig {

    // 使用@Bean注解, 将docket注册为IOC容器中的Bean节点
    @Bean
    public Docket docket() {
        // 返回值为新建一个Docket类, 其构造函数的参数为DocumentationType.SWAGGER_2(表示文档类型为Swagger2)
        return new Docket(DocumentationType.SWAGGER_2)
                // 将apiInfo设置为自定义的
                .apiInfo(myApiInfo())
                // Api的选择器
                .select()
                // 设置api信息, 传入参数为RequestHandlerSelectors(请求控制器选择器), 配置basePackage信息(扫描指定的基本包路径)
                .apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
            // 设置过滤的路径(使用ant进行匹配, 过滤掉不以"/kuang/**"开头的请求路径)
                .paths(PathSelectors.ant("/kuang/**"))
                // 构建(设计思想为工厂模式)
                .build();
    }

    // 配置Swagger信息apiInfo
    private ApiInfo myApiInfo() {

        // 作者的名字, url和邮箱地址
        Contact contact = new Contact("狂奔de蜗牛rz","https://mp.csdn.net/?spm=1000.2115.3001.4503","1441505359@qq.com");
        // 返回值为创建一个新的ApiInfo类, 设置基本信息
        return new ApiInfo("自定义SwaggerApi文档",
                            "乘风破浪会有时, 直挂云帆济沧海",
                            "V1.0",
                            "http://localhost:8080/hello",
                             contact,
                            "Apache 2.0",
                            "http://www.apache.org/licenses/LICENSE-2.0",
                            new ArrayList<>());
    }

}
  • 访问swagger-ui页面API文档信息

SpringBoot基础学习之整合Swagger框架(上篇)

3.其他的设置扫描情况

  • 设置扫描所有的包路径
package com.kuang.swagger.config;

/**
 * @ClassName SwaggerConfig
 * @Description Swagger配置类
 * @Author 狂奔de蜗牛rz
 * @Date 2021/10/1
 */

// 将SwaggerConfig类注册为配置类
@Configuration
// 开启Swagger2的支持
@EnableSwagger2
public class SwaggerConfig {

    // 使用@Bean注解, 将docket注册为IOC容器中的Bean节点
    @Bean
    public Docket docket() {
        // 返回值为新建一个Docket类, 其构造函数的参数为DocumentationType.SWAGGER_2(表示文档类型为Swagger2)
        return new Docket(DocumentationType.SWAGGER_2)
                // 将apiInfo设置为自定义的
                .apiInfo(myApiInfo())
                // Api的选择器
                .select()
                //扫描所有的包路径
                .apis(RequestHandlerSelectors.any())
                // 构建(设计思想为工厂模式)
                .build();
    }

    // 配置Swagger信息apiInfo
    private ApiInfo myApiInfo() {

        // 作者的名字, url和邮箱地址
        Contact contact = new Contact("狂奔de蜗牛rz","https://mp.csdn.net/?spm=1000.2115.3001.4503","1441505359@qq.com");
        // 返回值为创建一个新的ApiInfo类, 设置基本信息
        return new ApiInfo("自定义SwaggerApi文档",
                            "乘风破浪会有时, 直挂云帆济沧海",
                            "V1.0",
                            "http://localhost:8080/hello",
                             contact,
                            "Apache 2.0",
                            "http://www.apache.org/licenses/LICENSE-2.0",
                            new ArrayList<>());
    }

}
  • 设置不扫描任何包路径
package com.kuang.swagger.config;

/**
 * @ClassName SwaggerConfig
 * @Description Swagger配置类
 * @Author 狂奔de蜗牛rz
 * @Date 2021/10/1
 */

// 将SwaggerConfig类注册为配置类
@Configuration
// 开启Swagger2的支持
@EnableSwagger2
public class SwaggerConfig {

    // 使用@Bean注解, 将docket注册为IOC容器中的Bean节点
    @Bean
    public Docket docket() {
        // 返回值为新建一个Docket类, 其构造函数的参数为DocumentationType.SWAGGER_2(表示文档类型为Swagger2)
        return new Docket(DocumentationType.SWAGGER_2)
                // 将apiInfo设置为自定义的
                .apiInfo(myApiInfo())
                // Api的选择器
                .select()
                // 不扫描任何包路径
                .apis(RequestHandlerSelectors.none())
                // 构建(设计思想为工厂模式)
                .build();
    }

    // 配置Swagger信息apiInfo
    private ApiInfo myApiInfo() {

        // 作者的名字, url和邮箱地址
        Contact contact = new Contact("狂奔de蜗牛rz","https://mp.csdn.net/?spm=1000.2115.3001.4503","1441505359@qq.com");
        // 返回值为创建一个新的ApiInfo类, 设置基本信息
        return new ApiInfo("自定义SwaggerApi文档",
                            "乘风破浪会有时, 直挂云帆济沧海",
                            "V1.0",
                            "http://localhost:8080/hello",
                             contact,
                            "Apache 2.0",
                            "http://www.apache.org/licenses/LICENSE-2.0",
                            new ArrayList<>());
    }
    
}
  • 设置扫描类上的注解
package com.kuang.swagger.config;

/**
 * @ClassName SwaggerConfig
 * @Description Swagger配置类
 * @Author 狂奔de蜗牛rz
 * @Date 2021/10/1
 */

//将SwaggerConfig类注册为配置类
@Configuration
// 开启Swagger2的支持
@EnableSwagger2
public class SwaggerConfig {

    // 使用@Bean注解, 将docket注册为IOC容器中的Bean节点
    @Bean
    public Docket docket() {
        // 返回值为新建一个Docket类, 其构造函数的参数为DocumentationType.SWAGGER_2(表示文档类型为Swagger2)
        return new Docket(DocumentationType.SWAGGER_2)
                // 将apiInfo设置为自定义的
                .apiInfo(myApiInfo())
                // Api的选择器
                .select()
                // 扫描类上的注解(其参数为注解的反射对象)
              .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                // 构建(设计思想为工厂模式)
                .build();
    }

    // 配置Swagger信息apiInfo
    private ApiInfo myApiInfo() {

        // 作者的名字, url和邮箱地址
        Contact contact = new Contact("狂奔de蜗牛rz","https://mp.csdn.net/?spm=1000.2115.3001.4503","1441505359@qq.com");
        // 返回值为创建一个新的ApiInfo类, 设置基本信息
        return new ApiInfo("自定义SwaggerApi文档",
                            "乘风破浪会有时, 直挂云帆济沧海",
                            "V1.0",
                            "http://localhost:8080/hello",
                             contact,
                            "Apache 2.0",
                            "http://www.apache.org/licenses/LICENSE-2.0",
                            new ArrayList<>());
    }
    
}
  • 设置扫描方法上的注解
package com.kuang.swagger.config;

/**
 * @ClassName SwaggerConfig
 * @Description Swagger配置类
 * @Author 狂奔de蜗牛rz
 * @Date 2021/10/1
 */

//将SwaggerConfig类注册为配置类
@Configuration
// 开启Swagger2的支持
@EnableSwagger2
public class SwaggerConfig {

    // 使用@Bean注解, 将docket注册为IOC容器中的Bean节点
    @Bean
    public Docket docket() {
        // 返回值为新建一个Docket类, 其构造函数的参数为DocumentationType.SWAGGER_2(表示文档类型为Swagger2)
        return new Docket(DocumentationType.SWAGGER_2)
                // 将apiInfo设置为自定义的
                .apiInfo(myApiInfo())
                // Api的选择器
                .select()
                // 扫描方法上的注解
                .apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))
                // 构建(设计思想为工厂模式)
                .build();
    }

    // 配置Swagger信息apiInfo
    private ApiInfo myApiInfo() {

        // 作者的名字, url和邮箱地址
        Contact contact = new Contact("狂奔de蜗牛rz","https://mp.csdn.net/?spm=1000.2115.3001.4503","1441505359@qq.com");
        // 返回值为创建一个新的ApiInfo类, 设置基本信息
        return new ApiInfo("自定义SwaggerApi文档",
                            "乘风破浪会有时, 直挂云帆济沧海",
                            "V1.0",
                            "http://localhost:8080/hello",
                             contact,
                            "Apache 2.0",
                            "http://www.apache.org/licenses/LICENSE-2.0",
                            new ArrayList<>());
    }
    
}

好了,今天的有关 SpringBoot基础学习之整合Swagger框架(上篇) 的学习就到此结束啦,欢迎小伙伴们积极学习和讨论,喜欢的可以给蜗牛君点个关注,顺便来个一键三连,我们下期见,拜拜啦!


参考博客链接:https://zhuanlan.zhihu.com/p/40819897 (SpringFox 初体验)


参考视频链接:https://www.bilibili.com/video/BV1PE411i7CV(【狂神说Java】SpringBoot最新教程IDEA版通俗易懂)

上一篇:GlobalExceptionHandler @ControllerAdvice


下一篇:springboot实现swagger Api文件和日志处理