前后端分离必备工具:SpringBoot集成Swagger超详细教程

深渊向深渊呼唤

目录

1. 新建springboot项目 2. 导入Swagger依赖 3. 编写HelloController测试 4. 编写Swagger配置类 5. 测试进入Sawgger页面 6. 配置Swagger API信息 7. 配置Swagger自定义扫描接口 8. 配置是否启动Swagger 9. 配置API文档分组 1. 设置默认组名 2. 配置多个组 10. 配置Model实体类 1. 新建实体类 2. 编写对应请求接口 3. 启动测试 4. 常用注解 11. 测试Swagger的使用 1. 测试传参 2. 测试错误

1. 新建springboot项目

首先新建一个spirngboot项目,勾选组件时勾选Spring-Web



2. 导入Swagger依赖

springfox-swagger2

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>3.0.0</version>
</dependency>

springfox-swagger-ui

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>3.0.0</version>
</dependency>


3. 编写HelloController测试

我们编写一个controller来测试一下项目是否搭建成功,在主程序同级目录下新建controller包,其中新建HelloController

package com.zsr.controller;

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

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }
}

然后启动主程序,访问localhost:8080/hello,出现如下结果即成功
image-20201023183014921



4. 编写Swagger配置类

在主程序同级目录下新建config包,其中新建SwaggerConfig配置类

记住用@Configuration注解注明这是配置类 同时用@EnableSwagger2注解开启Swagger2
package com.zsr.config;

import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2//开启Swagger2
public class SwaggerConfig {

}


5. 测试进入Sawgger页面

重启主程序,访问localhost:8080/swagger-ui.html

启动报错:@EnableSwagger2注解找不到,但是已经导入了对应的jar包

image-20201023185624449
这时候降级为2.9.2即可使用

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.9.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.9.2</version>
</dependency>

再次启动主程序即可成功,然后访问localhost:8080/swagger-ui.html,即可进入到以下界面
image-20201023205134046
这个界面是Swagger为我们提供的ui界面,我们可以在源码中找到它
image-20201023212945475



6. 配置Swagger API信息

image-20201025220813224

在Swagger提供的ui界面,其中的Swagger信息模块我们可以自定义信息内容

我们只需要在Swagger配置类SwaggerConfig中实例化Docket类队对象的bean实例,通过配置ApiInfo类的信息然后传入Docket的bean实例即可

image-20201023212301978

package com.zsr.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.service.VendorExtension;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

@Configuration
@EnableSwagger2//开启Swagger2
public class SwaggerConfig {
    //配置Swagger的Docket的bean实例
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo());//配置Swagger信息
    }

    //配置Swagger信息
    private ApiInfo apiInfo() {
        return new ApiInfo(
                "Baret-H",
                "我的Swagger API文档",
                "1.0",
                "https://bareth.blog.csdn.net/",
                new Contact("Baret-H", "https://bareth.blog.csdn.net/", "1412578784@qq.com"),//作者信息
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList<VendorExtension>());
    }
}

重启主程序测试,可以看到Swagger信息已经变更成我们定义的信息
image-20201023212154292



7. 配置Swagger自定义扫描接口

我们在这个ui界面中,可以看到扫描了两个controller接口

image-20201023213154765

一个是默认的/error请求,也就是我们启动springboot主程序未加配置默认访问8080端口的默认controller
image-20201023213519690

另一个是我们自己写的/hello请求,对应着HelloController,由于我们用的@RequsetMapping注解,所以请求的方式有以上的六种

接下来我们自己配置以下要扫描的接口

@Bean
public Docket docket() {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())//配置Swagger信息
            .select()
            /**
             * apis():指定扫描的接口
             *  RequestHandlerSelectors:配置要扫描接口的方式
             *       basePackage:指定要扫描的包
             *       any:扫面全部
             *       none:不扫描
             *       withClassAnnotation:扫描类上的注解(参数是类上注解的class对象)
             *       withMethodAnnotation:扫描方法上的注解(参数是方法上的注解的class对象)
             */
            .apis(RequestHandlerSelectors.basePackage("com.zsr.controller"))
            /**
             * paths():过滤路径
             *  PathSelectors:配置过滤的路径
             *      any:过滤全部路径
             *      none:不过滤路径
             *      ant:过滤指定路径:按照按照Spring的AntPathMatcher提供的match方法进行匹配
             *      regex:过滤指定路径:按照String的matches方法进行匹配
             */
            .paths(PathSelectors.ant("/zsr/**"))
            .build();
}

其中.select().apis.paths.build是一套组合进行使用

然后我们启动主程序访问localhost:8080/swagger-ui.html进行测试
image-20201025160758501
可以发现No opertations defined in spec,这是因为我们过滤了/zsr下的所有controller

我们将过滤条件更改为过滤全部路径

.paths(PathSelectors.any)

再次启动主程序访问localhost:8080/swagger-ui.html
image-20201025161212037
可以看到只显示了我们上述自定义的com.zsr.controller下的接口HelloController

.apis(RequestHandlerSelectors.basePackage("com.zsr.controller"))


8. 配置是否启动Swagger

我么通过Docket对象的.enable方法来配置swagger是否启动

@Bean
public Docket docket() {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())//配置Swagger信息
            .enable(false)//配置是否启动swagger,默认为true
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.zsr.controller"))
            .paths(PathSelectors.ant("/zsr/**"))
            .build();
}

更改为false后启动测试一下,查看控制台,无法进入到swagger页面
image-20201023220447602

如果我们有这样一个需求:希望Swagger在开发环境中,在正式环境时不能使用

首先要判断是不是开发环境,可以设置一个flag表示用来表示:flag=1即表示生产环境 然后将flag的值传给enable(flag)

首先在resources目录下新建两种springboot配置文件:

开发环境:application-dev.properties

server.port=8081

正式环境:application-pro.properties

server.port=8082
image-20201023233834369

然后在主配置文件application.properties中激活开发环境

spring.profiles.active=dev

然后我们到SwaggerConfig中的docket()方法中添加代码:

首先给该方法传一个参数Environment的实例

Environment environment

首先设置药配置的Swagger环境:这里可以添加多个环境

Profiles profiles = Profiles.of("dev", "test");

然后通过environment.acceptsProfiles方法判断是否处在上一步设定的dev/test环境中,返回一个boolean的值,我们用flag接收

boolean flag = environment.acceptsProfiles(profiles);

然后修改enable中的参数为flag,即通过flag来判断是否开启Swagger

.enable(flag)//通过flag判断是否开启

完整代码

@Configuration
@EnableSwagger2//开启Swagger2
public class SwaggerConfig {
    //配置Swagger的Docket的bean实例
    @Bean
    public Docket docket(Environment environment) {
        //设置要配置的Swagger环境
        Profiles profiles = Profiles.of("dev", "test");
        //通过environment.acceptsProfiles判断是否处在自己设定的环境中
        boolean flag = environment.acceptsProfiles(profiles);

        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())//配置Swagger信息
                .enable(flag)//通过flag判断是否开启
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.zsr.controller"))
                .paths(PathSelectors.ant("/zsr/**"))
                .build();
    }

    //配置Swagger信息
    private ApiInfo apiInfo() {
        return new ApiInfo(
                "Baret-H",
                "我的Swagger API文档",
                "1.0",
                "https://bareth.blog.csdn.net/",
                new Contact("Baret-H", "https://bareth.blog.csdn.net/", "1412578784@qq.com"),//作者信息
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList<VendorExtension>());
    }
}

然后启动主程序测试:由于激活了dev开发环境,所以访问localhost:8081/swagger-ui.html
image-20201025155757821
成功开启swagger,如果我们修改主配置文件,激活pro正式发布环境

spring.profiles.active=pro

再次重启主程序测试,访问端口8082对应的地址localhost:8082/swagger-ui.html
image-20201025155948810
无法进入,因为pro环境不在我们配置的test/dev环境中,所以无法开启



9. 配置API文档分组

1. 设置默认组名

可以看到,我们默认只有一个组且组名为default
image-20201025163547341

我们可以在docket通过.groupName中设置组名

public Docket docket(Environment environment) {
    //设置要配置的Swagger环境
    Profiles profiles = Profiles.of("dev", "test");
    //通过environment.acceptsProfiles判断是否处在自己设定的环境中
    boolean flag = environment.acceptsProfiles(profiles);

    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())//配置Swagger信息
            .groupName("zsr")
            .enable(true)//配置是否启动swagger,默认为true
            .select()
            .apis(RequestHandlerSelectors.basePackage("com.zsr.controller"))
            .paths(PathSelectors.any())
            .build();
}

重启测试,可以看到组名更改为zsr
image-20201025163953771


2. 配置多个组

上述我们成功修改了组名,但是只有一个组,如果我们想要多个组呢?

观察代码可以知道,一个Docket实例就对应着一个组,因此我们配置多个docket就对应着多个组

我们新增两个Docket的bean实例

@Bean
public Docket docket1() {
    return new Docket(DocumentationType.SWAGGER_2).groupName("Baret-H");
}

@Bean
public Docket docket2() {
    return new Docket(DocumentationType.SWAGGER_2).groupName("钟");
}

再次重启测试,就可以看到多个组并选择

image-20201025164947559



10. 配置Model实体类

1. 新建实体类

在主程序同级目录下新建pojo包,其中新建User实体类

package com.zsr.pojo;

public class User {
    public String username;
    public String password;
}

2. 编写对应请求接口

编写完实体类,我们在model中还是看不到的,我们还需在HelloController中新增一个方法返回实体类的实例对象即可映射到实体项中

@GetMapping("/getUser")
public User getUser() {
    return new User();
}

3. 启动测试

成功显示实体类User

image-20201025172330524

4. 常用注解

我们可以在实体类上和其属性上添加注解来添加对应的注释

@ApiModel为类添加注释

@ApiModelProperty为类属性添加注释

package com.zsr.pojo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel("用户实体")
public class User {
    @ApiModelProperty("用户名")
    public String username;
    @ApiModelProperty("密码")
    public String password;
}

重启测试,即可以看到注释信息
image-20201025173636862

我们同样可以在Controller类和其中的方法上添加相应的注解

@Api(tags = "Hello控制类")
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
        return "hello";
    }

    @ApiOperation("hello控制类")
    @GetMapping("/getUser")
    public User getUser() {
        return new User();
    }
}

重启即可看到对应的注解
image-20201025175251278



11. 测试Swagger的使用

1. 测试传参

我们在HelloController中新增一个方法,参数为username,可以用@ApiParam给该参数添加注解

@GetMapping("/username")
public String getUserName(@ApiParam("用户名") String username) {
    return username;
}

重启测试,可以看到我们添加的注释
image-20201025180318626
我们可以简单测试一下,点击Try it out;然后以json的格式输入用户名,然后点击Execute执行
image-20201025211728843
可以看到报错了,这是因为我们是使用的是Get方式:是通过URL的方式传递的,而不是通过请求体单独传参
image-20201025211838700

我们将代码修改一下,将GetMapping改为PostMapping

@PostMapping("/username")
public String getUserName(@ApiParam("用户名") String username) {
    return username;
}

image-20201025212320277
再次以json的格式输入参数username,可以看到成功了
image-20201025212422153

2. 测试错误

我们在HelloController中新增一个方法,参数为User,可以用@ApiParam给该参数添加注解

然后运行测试
image-20201025214501614
找到对应的controller,点击Try it out测试,输入用户名和密码然后点击Excute
image-20201025214626100
可以看到我们请求的URL完全正确,但是Response body相应体中用户名和密码都为空,这是因为我们的实体类没有添加对应的GET和SET方法,我们添加上去

package com.zsr.pojo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel("用户实体")
public class User {
    @ApiModelProperty("用户名")
    public String username;
    @ApiModelProperty("密码")
    public String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

再次启动测试,成功!
image-20201025215501706
如果我们修改一下代码

@PostMapping("/post")
private User postUser(User user) {
    int i = 100 / 0;
    return user;
}

此时测试肯定会报错,我们测试看看,可以看到500错误
image-20201025215801946
由此可见,swagger可以让我们很容易的进行前后端的交互测试

栏目