定制化开发Swagger-的使用(详细教程)

文章目录


前言

定制化开发作为后端开放人员,定制化开发最烦的事就是自己写接定制化开发口文档和别人没有写接口文档,定制化开发不管是前端还是后端开发,定制化开发多多少少都会被接口文档所折磨,定制化开发前端会抱怨后端没有及定制化开发时更新接口文档,定制化开发而后端又会觉得编写接定制化开发口文档太过麻烦。 定制化开发可以较好的接口接口文定制化开发档的交互问题,定制化开发以一套标准的规范定义定制化开发接口以及相关的信息,定制化开发就能做到生成各种格式定制化开发的接口文档,定制化开发生成多种语言和客户端定制化开发和服务端的代码,定制化开发以及在线接口调试页面等等。定制化开发只需要更新 Swagger 描述文件,定制化开发就能自动生成接口文档,做到前端、定制化开发后端联调接口文档的及定制化开发时性和便利性。

一、简介

官网:

Swagger 定制化开发是一个规范且完整的框架,用于生成、描述、定制化开发调用和可视化 RESTful 风格的 Web 服务。

Swagger 定制化开发的目标是对 REST API 定制化开发定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过 Swagger 进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger 消除了调用服务时可能会有的猜测。

Swagger 的优势

  • 支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。
  • 提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试。参数和格式都定好了,直接在界面上输入参数对应的值即可在线测试接口。

二、基本使用

1. 导入相关依赖

通过在项目中引入 Springfox,可以扫描相关的代码,生成该描述文件,进而生成与代码一致的接口文档和客户端代码。

        <!-- swagger -->        <dependency>            <groupId>io.springfox</groupId>            <artifactId>springfox-spring-web</artifactId>            <version>2.9.2</version>        </dependency>        <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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2. 编写配置文件

在配置文件 config 目录下,添加 swagger 的配置文件 SwaggerConfig.java

@Configuration // 配置类@EnableSwagger2 // 开启 swagger2 的自动配置public class SwaggerConfig {}
  • 1
  • 2
  • 3
  • 4

这个时候 Swagger 已经算是整合到项目之中了,可以启动下服务,输入:http://localhost:8080/swagger-ui.html# (这里我的项目端口是 8868 ,项目路径是 /mike,所以我打开的文档地址为 http://localhost:8868/mike/swagger-ui.html# )即可查看 swagger 文档。


可以看到 Swagger 文档中大概有这四类信息

  • 基本信息
  • 接口信息
  • 实体类信息

2.1 配置基本信息

Swagger 有自己的实例 Docket,如果我们想要自定义基本信息,可以使用 docket 来配置 swagger 的基本信息,基本信息的设置在 ApiInfo 这个对象中。

Swagger 默认的基本信息展示

ApiInfo 中默认的基本设置

  • title:Api Documentation
  • description:Api Documentation
  • version:1.0
  • termsOfServiceUrl:urn:tos
  • contact:无
  • license:Apache 2.0
  • licenseUrl:http://www.apache.org/licenses/LICENSE-2.0

SwaggerConfig.java 配置文件添加以下内容:

    @Bean    public Docket docket() {        // 创建一个 swagger 的 bean 实例        return new Docket(DocumentationType.SWAGGER_2)                // 配置基本信息                .apiInfo(apiInfo())                ;    }    // 基本信息设置    private ApiInfo apiInfo() {        Contact contact = new Contact(                "米大傻", // 作者姓名                "https://blog.csdn.net/xhmico?type=blog", // 作者网址                "777777777@163.com"); // 作者邮箱        return new ApiInfoBuilder()                .title("多加辣-接口文档") // 标题                .description("众里寻他千百度,慕然回首那人却在灯火阑珊处") // 描述                .termsOfServiceUrl("https://www.baidu.com") // 跳转连接                .version("1.0") // 版本                .license("Swagger-的使用(详细教程)")                .licenseUrl("https://blog.csdn.net/xhmico/article/details/125353535")                .contact(contact)                .build();    }
  • 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

重启服务,打开 Swagger 文档,基本信息改变如下所示:

2.2 配置接口信息

默认情况下,Swagger 是会展示所有的接口信息的,包括最基础的 basic-error 相关的接口

有时候我们希望不要展示 basic-error-controller 相关的接口,或者是说这想要显示某些接口,比如说:user-controller 下的接口,由该怎么去实现呢?这个时候就需要设置 扫描接口

    @Bean    public Docket docket() {        // 创建一个 swagger 的 bean 实例        return new Docket(DocumentationType.SWAGGER_2)                // 配置接口信息                .select() // 设置扫描接口                // 配置如何扫描接口                .apis(RequestHandlerSelectors                        //.any() // 扫描全部的接口,默认                        //.none() // 全部不扫描                        .basePackage("com.duojiala.mikeboot.controller") // 扫描指定包下的接口,最为常用                        //.withClassAnnotation(RestController.class) // 扫描带有指定注解的类下所有接口                        //.withMethodAnnotation(PostMapping.class) // 扫描带有只当注解的方法接口                )                .paths(PathSelectors                        .any() // 满足条件的路径,该断言总为true                        //.none() // 不满足条件的路径,该断言总为false(可用于生成环境屏蔽 swagger)                        //.ant("/user/**") // 满足字符串表达式路径                        //.regex("") // 符合正则的路径                )                .build();    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

可根据自己的需求去设置对应的配置,这里我就不再一一赘述了,以上是我所设置的配置,重启服务,打开 Swagger 文档,接口信息改变如下所示:

可以看到之前 basic-error-controller 相关的接口已经没有了

2.3 配置分组信息

Swagger 默认只有一个 default 分组选项,如果没有设置,所有的接口都会显示在 default `分组下,如果功能模块和接口数量一多,就会显得比较凌乱,不方便查找和使用。

swagger 文档中组名默认是 default,可通过 .groupName(String )

    @Bean    public Docket docket() {        // 创建一个 swagger 的 bean 实例        return new Docket(DocumentationType.SWAGGER_2)                .groupName("mike") // 修改组名为 "mike"                ;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

修改后:

如果需要配置多个组的话,就需要配置多个 docket() 方法,这里我就简单写两组,代码如下:

    /**     * 展示 controller 包下所有的接口     */    @Bean    public Docket docket1() {        // 创建一个 swagger 的 bean 实例        return new Docket(DocumentationType.SWAGGER_2)                .groupName("mike") // 修改组名为 "mike"                // 配置接口信息                .select() // 设置扫描接口                // 配置如何扫描接口                .apis(RequestHandlerSelectors                        .basePackage("com.duojiala.mikeboot.controller") // 扫描指定包下的接口,最为常用                )                .paths(PathSelectors                         .any() // 满足条件的路径,该断言总为true                )                .build();    }    /**     * 展示路径为 /error 的所有接口(基础接口)     */    @Bean    public Docket docket2() {        // 创建一个 swagger 的 bean 实例        return new Docket(DocumentationType.SWAGGER_2)                .groupName("yank") // 修改组名为 "yank"                // 配置接口信息                .select() // 设置扫描接口                // 配置如何扫描接口                .apis(RequestHandlerSelectors                        .any() // 扫描全部的接口,默认                )                .paths(PathSelectors                        .ant("/error") // 满足字符串表达式路径                )                .build();    }
  • 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

重启服务,打开 Swagger 文档,接口信息改变如下所示:

组名为 mike 的文档中只有 user-controller 相关的接口信息

组名为 yank 的文档中只有 basic-error-controller 相关的接口信息


3. 控制 Swagger 的开启

在开发或者测试环境下,我们开启 swagger 会方便前端和后端的交互,但是如果在生产环境下也开启 swagger 的话,是会将接口暴露出去的,有极大风险,如何让 swagger 根据不同的环境来决定是否开启?

这里我准备了四个项目的配置文件,devtestpro 三个环境的配置文件仅是端口上的不同

  • application.yml -------------------------- 全局配置文件
  • application-dev.yml -------------------- 开发环境配置文件
  • application-test.yml -------------------- 测试环境配置文件
  • application-pro.yml -------------------- 生产环境配置文件

application.yml 内容如下,用于指定选择的环境:

spring:  profiles:    active: dev
  • 1
  • 2
  • 3

可以通过代码判断此时是在什么环境:devtestpro,如果是在 pro 生产环境,则关闭 swagger。

    /**     * swagger 配置     * @param environment 环境     */    @Bean    public Docket docket(Environment environment) {        // 设置环境范围        Profiles profiles = Profiles.of("dev","test");        // 如果在该环境返回内则返回:true,反之返回 false        boolean flag = environment.acceptsProfiles(profiles);        // 创建一个 swagger 的 bean 实例        return new Docket(DocumentationType.SWAGGER_2)                .enable(flag) // 是否开启 swagger:true -> 开启,false -> 关闭                ;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

application.yml 全局配置文件中环境指向 dev 时,是可以打开 swagger 的


如果我将 application.yml 全局配置文件中环境指向 pro 时,就不能打开 swagger 了,提示 Could not render e, see the console

4. 常用注解使用

之前有说 Swagger 会将接口请求或者相应的实体类信息展示在 Models 下的,比如我 UserController.java 下有一个接口如下所示:

    @PostMapping(value = "/query-user-info")    public ResponseBean queryUserInfo(@RequestBody @Validated IdReq req) {        return ResponseBean.success(userService.queryUserInfo(req));    }
  • 1
  • 2
  • 3
  • 4

它的请求体是 IdReq,响应是 ResponseBeanModels 展示这两个实体类信息如下:


前端可通过看这个 Models 知道后端定义实体类的信息。

@

该注解是作用于类上面的,是用来描述类的一些基本信息的。

相关属性:

  • value:提供类的一个备用名,如果不设置,默认情况下将使用 class 类的名称
  • description:对于类,提供一个详细的描述信息
  • parent:这个属性用于描述的是类的一些父类信息
  • discriminator:这个属性解释起来比较麻烦,因为这个类主要体现在断言当中
  • subTypes:可以通过这个属性,指定我们想要使用的子类

譬如:这个为给 IdReq 这个类添加该注解

@Data@NoArgsConstructor@AllArgsConstructor@ApiModel(value = "Id请求体")public class IdReq {    private String id;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7


可以看到这里的名字从 IdReq 变成 Id请求体

@

它的作用是添加和操作属性模块的数据。

该注解的使用详情可参见博客:

这里我还是以 IdReq 类为例,为该类的属性添加说明

@Data@NoArgsConstructor@AllArgsConstructor@ApiModel(value = "Id请求体")public class IdReq {    @ApiModelProperty("主键id")    private String id;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8


可以看到这里对该字段有一个备注说明。

@ApiOperation

该注解用来对某个方法/接口进行描述

该注解的使用详情可参见博客:

这里我以 UserController 下的接口为例:

    @PostMapping(value = "/query-user-info")    @ApiOperation(value = "根据id查询用户详情")    public ResponseBean queryUserInfo(@RequestBody @Validated IdReq req) {        return ResponseBean.success(userService.queryUserInfo(req));    }
  • 1
  • 2
  • 3
  • 4
  • 5


可以看见该接口就多了对其的描述信息。

@ApiParam

该注解使用在方法上或者参数上,字段说明,表示对参数的添加元数据(说明或者是否必填等)

相关属性:

  • name:参数名
  • value:参数说明
  • required:是否必填

这里我以 UserController 下的接口为例:

    @PostMapping(value = "/query-user-infos")    @ApiOperation(value = "条件查询用户信息")    public ResponseBean queryUserInfos(            // name 用户名称 不必填            @ApiParam(value = "用户名称", required = false) @RequestParam(required = false) String name,            // gender 用户性别 必填            @ApiParam(value = "用户性别", required = true) @RequestParam(required = true) GenderEnum gender    ) {        return ResponseBean.success(userService.queryUserInfos(name,gender));    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10


这里会展示请求参数的备注信息,以及是否必填等。

5. 接口调用

使用 swagger 除了让前后端交互变得方便,也让接口的请求变得简单,只需要填写好请求所需要的参数信息,便可直接发起请求。

比如说接口 /user/query-user-info

点击 Try it out


设置好请求所需的参数,点击 Execute 执行

就能看到接口响应的结果了

接口 /user/query-user-infos 也差不多



三、进阶使用

1. 添加请求头

有时候我们的接口是需要获取请求头信息的,这样的话就还需要在 swagger 配置中添加请求头的配置。

    @Bean    public Docket docket() {        // 设置请求头        List<Parameter> parameters = new ArrayList<>();        parameters.add(new ParameterBuilder()                .name("token") // 字段名                .description("token") // 描述                .modelRef(new ModelRef("string")) // 数据类型                .parameterType("header") // 参数类型                .defaultValue("default value") // 默认值:可自己设置                .hidden(true) // 是否隐藏                .required(false) // 是否必须                .build());        // 创建一个 swagger 的 bean 实例        return new Docket(DocumentationType.SWAGGER_2)                .groupName("mike") // 修改组名为 "mike"                // 配置接口信息                .select() // 设置扫描接口                // 配置如何扫描接口                .apis(RequestHandlerSelectors                        .basePackage("com.duojiala.mikeboot.controller") // 扫描指定包下的接口,最为常用                )                .paths(PathSelectors                        .any() // 满足条件的路径,该断言总为true                )                .build()                // 添加请求头参数                .globalOperationParameters(parameters);    }
  • 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

比如接口:

    @GetMapping(value = "/get-token")    @ApiOperation(value = "获取请求头中的token信息")    public void getToken(            @RequestHeader(value = "token",required = false) String token    ) {        // 直接获取 token 信息        System.out.println("token = " + token);        // 通过代码获取        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();        if (servletRequestAttributes != null) {            HttpServletRequest request = servletRequestAttributes.getRequest();            String header = request.getHeader("token");            System.err.println("header = " + header);        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16


可以看到这个接口已经可以去设置请求头了,调用接口


后端也能获取到。

四、项目下载

以下是我这个项目所编写的代码
链接:
提取码:na2o

相关博客:

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发