h

hjxxxxxx

V1

2022/09/28阅读:37主题:简

Swagger 使用指南

Swagger 使用指南

一. 前后端分离

什么是前后端分离 : 前后端分离就是将前端视图和后端数据进行分离

1. HTML 时代

HTML 负责定义页面,java 通过 jsp 等模板引擎渲染数据.(前后端不分家,独立完成界面和业务)

2. 前后端分离时代

2.1. 前后端分离时代发展期

  • 前端 控制层,视图层 (mock后端数据 json,已经存在,不需要后端即可工作)
  • 后端 控制层,服务层,数据访问层 (完成主要逻辑,不再需要关心页面)

前后端交互约定方式

  • 手动维护的 api 文档 (world等)

产生一个问题

  • 前后端集成联调,前端人员和后端人员无法做到"即时协商,尽早解决".
  • 文档存在"滞后性".

2.2. 前后端分离时代成熟期

  • 首先制定一个 schema(计划)
  • 实时更新最新的api
  • 后端提供接口,实时更新最新文档

在长久的实践中,Swagger 诞生了

二. Swagger

  • 世界最流行的Api框架
  • Restful Api文档自动生成 文档与定义同步更新
  • 直接运行,可在线测试API接口
  • 支持主流开发语言 Java php python go ...

1. 在项目中使用Swagger需要什么

  • Swagger2 - 核心依赖
  • UI - UI界面
<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. 最简单集成swagger

  1. spring-boot 版本 2.2.0.RELEASE
  2. swagger 版本 2.9.2
  3. 默认扫描所有接口

集成步骤

  1. 导入依赖
  2. 编写一个 Bean 注入 Springboot
  3. 启用 Swagger2

2.1. 导入依赖

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

2.2. 启用 Swagger2

@EnableSwagger2 可写在任何地方,能被 Springboot 扫描到即可

@Configuration
@EnableSwagger2
public class SwaggerConfig {
}

3. Swagger 进阶

3.1. 配置Swagger

Docket 配置 Swagger 的插件

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2);
    }
}

3.2. 配置基础apiinfo

ApiInfo 定义了 Swagger 的所有基础信息

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo());
    }
    
    private ApiInfo apiInfo(){
        return new ApiInfo(
                "Title of Api Documentation",
                "Desc of Api Documentation",
                "version 1.0",
                "team url",
                new Contact( // 联络人,定义该接口文档的负责人信息
                        "name",
                        "url",
                        "email"
                ),
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList() // 拓展 ,一般设为empty
        );

    }
}

3.3. 接口扫描配置

选择器通过select()开启,build()构建.

  1. 针对包,注解的扫描 .apis
  2. 针对 Restful 路径的扫描 .paths

只扫描 org.example.controller 包下,匹配/api/**的接口.

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage("org.example.controller"))
            .paths(PathSelectors.ant("/api/**"))
            .build()
            ;
    }
}

.apis 支持的值

.apis(RequestHandlerSelectors.basePackage("org.example.controller")) // 根据包路径扫描接口
.apis(RequestHandlerSelectors.any()) // 扫描所有,项目中的所有接口都会被扫描到
.apis(RequestHandlerSelectors.none()) // 不扫描接口
.apis(RequestHandlerSelectors.withClassAnnotation(ResponseBody.class)) // 通过类上的注解扫描
.apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class)) // 通过方法上的注解扫描

.paths 支持的值

.paths(PathSelectors.any()) // 扫描所有,项目中的所有接口都会被扫描到
.paths(PathSelectors.ant("/api/**")) // 通配符过滤
.paths(PathSelectors.none()) // 不扫描接口
.paths(PathSelectors.regex("/api/v[1-2]")) // 正则过滤

3.4. 针对环境控制 Swagger 开启关闭

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket docket(Environment environment){

        // 获取环境
        Profiles dev = Profiles.of("dev","test");
        // 判断当前环境是否与 Profiles 环境存在 match
        boolean flag = environment.acceptsProfiles(dev);

        return new Docket(DocumentationType.SWAGGER_2)
                .enable(flag)
                ;
    }
}

3.5. Swagger 分组

写多个 Docket,由 Spring 接管, Swagger 整合

@Bean
public Docket docket1(){
    return new Docket(DocumentationType.SWAGGER_2).groupName("A"));
}
@Bean
public Docket docket2(){
    return new Docket(DocumentationType.SWAGGER_2).groupName("B"));
}
@Bean
public Docket docket3(){
    return new Docket(DocumentationType.SWAGGER_2).groupName("C"));
}

3.6. Swagger 切换皮肤

Swagger 皮肤很多,使用时只需要引入一个皮肤就行了,无需做任何额外配置

这里只列举两个常用的皮肤

3.6.1. 官方皮肤

访问地址: http://127.0.0.1:8080/swagger-ui.html

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

访问地址: http://127.0.0.1:8080/doc.html

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-ui</artifactId>
    <version>3.0.3</version>
</dependency>

4. 其他

4.1. 隐藏 basic-error-controller

每当一个Springboot项目启动时,都会默认注册一个basic-error-controller,如果采用默认的 Swagger 配置,该Controller会被扫描进 Swagger,配置接口扫描可以排除.

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket docket(){
        return new Docket(DocumentationType.SWAGGER_2)
            .select()
            .apis(RequestHandlerSelectors.basePackage("org.example.controller"))
            .build()
            ;
    }
}

4.2. Springboot 高版本与 Swagger 低版本不兼容(高版本也不兼容)

Springboot 2.6.0 及以上不再支持 Swagger 2.9.2 及以下

出现原因: SpringBoot处理映射匹配的默认策略发生变化

解决办法: 配置 spring.mvc.pathmatch.matching-strategy=ant-path-matcher

springboot 2.6.0之前

public static class Pathmatch {
 private MatchingStrategy matchingStrategy = MatchingStrategy.ANT_PATH_MATCHER;
}

springboot2.6.0之后

public static class Pathmatch {
    private MatchingStrategy matchingStrategy = MatchingStrategy.PATH_PATTERN_PARSER;
}

4.3. Sawgger2 与 Swagger3的区别

4.3.1. 访问路径
版本 访问地址
3.0.0之前 http://127.0.0.1:8080/swagger-ui.html
3.0.0之后 http://127.0.0.1:8080/swagger-ui/index.html
4.3.2. 注解变化

Sawgger2 和 Sawgger3 的注解发生了很大的变化.

4.4. Swagger2 注解一览

> 类

@Api:用在请求的类上,表示对类的说明
    tags="说明该类的作用,可以在UI界面上看到的注解"
    value="该参数没什么意义,在UI界面上也看到,所以不需要配置"

> 方法

@ApiOperation:用在请求的方法上,说明方法的用途、作用
    value="说明方法的用途、作用"
    notes="方法的备注说明"

@ApiImplicitParams:用在请求的方法上,表示一组参数说明
    @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
        name:参数名
        value:参数的汉字说明、解释
        required:参数是否必须传
        paramType:参数放在哪个地方
            · header --> 请求参数的获取:@RequestHeader
            · query --> 请求参数的获取:@RequestParam
            · path(用于restful接口)--> 请求参数的获取:@PathVariable
            · body(不常用)
            · form(不常用)    
        dataType:参数类型,默认String,其它值dataType="Integer"       
        defaultValue:参数的默认值

@ApiResponses:用在请求的方法上,表示一组响应
    @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
        code:数字,例如400
        message:信息,例如"请求参数没填好"
        response:抛出异常的类

> 响应类

@ApiModel:用于响应类上,表示一个返回响应数据的信息
            (这种一般用在post创建的时候,使用@RequestBody这样的场景,
            请求参数无法使用@ApiImplicitParam注解进行描述的时候)
            
@ApiModelProperty:用在属性上,描述响应类的属性

@Api(tags="APP用户注册Controller")

@ApiOperation(value="用户注册",notes="手机号、密码都是必输项,年龄随边填,但必须是数字")

@ApiImplicitParams({
    @ApiImplicitParam(name="mobile",value="手机号",required=true,paramType="form"),
    @ApiImplicitParam(name="password",value="密码",required=true,paramType="form"),
    @ApiImplicitParam(name="age",value="年龄",required=true,paramType="form",dataType="Integer")
})

@ApiOperation(value = "select1请求",notes = "多个参数,多种的查询参数类型")
@ApiResponses({
    @ApiResponse(code=400,message="请求参数没填好"),
    @ApiResponse(code=404,message="请求路径没有或页面跳转路径不对")
})

@ApiModel(value= "返回响应数据")

@ApiModelProperty(value = "是否成功")

分类:

后端

标签:

后端

作者介绍

h
hjxxxxxx
V1