1 Star 0 Fork 0

Aladdin / swagger-demo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

Swagger 的使用

前言

后端时代

  • 前端:只用管理静态页面:html。
  • 后端:模板引擎 JSP,后端是主力

前后端分离时代

主流框架:Vue + SpringBoot

  • 后端:后端控制层,服务层,数据访问层【后端团队】
  • 前端:前端控制层,视图层【前端团队】
    • 伪造后端数据:json假数据。不需要请求后端,仅前端工程已经可以启动并操作。

前后端通过 API 接口进行交互,相对独立,松耦合,可以部署在不同的服务器上

前端后分离存在的问题:

  • 前后端集成联调,前端人员和后端人员无法做到“及时协商,尽早解决”,最终导致问题集中爆发;

解决方案:

  • 首先制定 schema (计划的提纲),试试更新最新 API ,降低集成风险;
  • 早期:制定word计划文档;
  • 前后端分离:
    • 后端接口测试工具:postman
    • 后端向前端提供接口,需要实时更新罪行的消息及改动!

Swagger 简介

  • 号称世界上最流程的 Api 框架;
  • 在线自动生成 RestFul Api 文档,该文档与 Api 接口信息同步更新;
  • 直接运行,可在线测试 Api 接口;
  • 支持多种语言:Java、Php ...

官网:

  • https://swagger.io/

使用:

  • 在项目中使用 Swagger 需要两个 springfox 依赖:
    • springfox-swagger2
    • springfox-swagger-ui

SpringBoot 集成 Swagger 2.x

  1. 新建一个 SpringBoot 项目(web 项目);

  2. 导入依赖

    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
        <exclusions>
            <exclusion>
                <!--
                io.springfox:springfox-swagger2:2.9.2中依赖了swagger-models的1.5.20版本,
                通过排除springfox-swagger2中的swagger-models依赖,导入io.swagger:swagger-models的1.5.21版本.
                解决io.swagger.models.parameters.AbstractSerializableParameter实例化参数时example为空字符串""而报错的问题.
                因为1.5.20的example只判断是否为null,1.5.21判断了是否为null和""
                -->
                <groupId>io.swagger</groupId>
                <artifactId>swagger-models</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/io.swagger/swagger-models -->
    <dependency>
        <groupId>io.swagger</groupId>
        <artifactId>swagger-models</artifactId>
        <version>1.5.22</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>
  3. 编写一个 Hello 工程;

  4. 在主程序上添加注解,开启 Swagger2

    @SpringBootApplication
    //开启 Swagger2
    @EnableSwagger2
    public class SwaggerDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SwaggerDemoApplication.class, args);
        }
    
    }
  5. 测试运行,访问 Swagger UI 界面

    http://localhost:8080/swagger-ui.html

SpringBoot 集成 Swagger 3.0

  1. 新建一个 SpringBoot 项目(web项目);

  2. 导入依赖

    <!-- https://mvnrepository.com/artifact/io.springfox/springfox-boot-starter -->
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-boot-starter</artifactId>
        <version>3.0.0</version>
    </dependency>
  3. 编写一个 Hello 工程;

  4. 在主程序上添加注解,开启Swagger

    @SpringBootApplication
    //开启 Swagger
    @EnableOpenApi
    public class SwaggerDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SwaggerDemoApplication.class, args);
        }
    
    }
  5. 测试运行,访问 Swagger UI 界面 注意:路径同 Swagger 2.x 不同

    http://localhost:8080/swagger-ui/index.html

配置 Swagger

配置文档信息

Swagger 的 bean 实例:Docket

Docket.apiInfo(ApiInfo apiInfo)方法

具体配置

@Configuration
public class SwaggerConfig {

    /**
     * 配置 Swagger Docket 的 bean实例
     *
     * @return Docket 的 bean实例
     */
    @Bean
    public Docket docket() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo());
    }

    /**
     * 配置 swagger 的信息:ApiInfo
     *
     * @return ApiInfo 的 bean实例
     */
    public ApiInfo apiInfo() {

        //作者信息
        Contact contact = new Contact("小聪", "https://blog.csdn.net/weixin_52610802?type=blog", "coder_cong@163.com");

        return new ApiInfo("Aladdin的SwaggerAPI文档",
                "不负韶华,未来可期",
                "V1.0",
                "https://blog.csdn.net/weixin_52610802?type=blog",
                contact,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList());
    }

}

配置扫描接口

Docket.select()方法

具体配置

/**
 * 配置 Swagger Docket 的 bean实例
 *
 * @return Docket 的 bean实例
 */
@Bean
public Docket docket() {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .select()
            /*
            RequestHandlerSelectors 配置扫描接口的方式
                basePackage():指定要扫描的包(通常指定包扫描)
                any():扫描全部
                none():不扫描
                withMethodAnnotation():扫描方法上的注解
                withClassAnnotation():方法类上的注解
             */
            .apis(RequestHandlerSelectors.basePackage("com.aladdin.swagger.controller"))
            /*
            PathSelectors 请求路径匹配的方式
                regex():正则匹配
                any():扫描全部
                none():不扫描
                ant():路径匹配
             */
            .paths(PathSelectors.ant("/aladdin/**"))
            .build();
}

配置功能是否启动

Docket.enable(boolean externallyConfiguredFlag)方法

具体配置

/**
 * 配置 Swagger Docket 的 bean实例
 *
 * @return Docket 的 bean实例
 */
@Bean
public Docket docket() {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            //是否启动 Swagger,如果为 false,则 UI界面提示:【😱 Could not render e, see the console.】,无法在浏览器中访问 Swagger
            .enable(false)
            .select()
         	.apis(RequestHandlerSelectors.basePackage("com.aladdin.swagger.controller"))
            .paths(PathSelectors.ant("/aladdin/**"))
            .build();
}

实用案例

  • 根据服务环境动态配置 Swagger 是否开启。
/**
 * 配置 Swagger Docket 的 bean实例
 *
 * @return 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,如果为 false,则 UI界面提示:【😱 Could not render e, see the console.】,无法在浏览器中访问 Swagger
            .enable(flag)
            .select()
         	.apis(RequestHandlerSelectors.basePackage("com.aladdin.swagger.controller"))
            .paths(PathSelectors.ant("/aladdin/**"))
            .build();
}

配置 API 文档的分组

Docket.groupName(String groupName)方法

具体配置

/**
 * 配置 Swagger Docket 的 bean实例
 *
 * @return Docket 的 bean实例
 */
@Bean
public Docket docket(Environment environment) {
    return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(apiInfo())
            .enable(true)
            //设置组名称,一个 Docket bean 对应一个组名称
            .groupName("阿拉丁")
            .apis(RequestHandlerSelectors.basePackage("com.aladdin.swagger.controller"))
            //.paths(PathSelectors.ant("/aladdin/**"))
            .build();
}

配置多个分组

配置多个分组,需配置多个 Docket bean,每个 bean 配置各自的 groupName

package com.aladdin.swagger.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
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 java.util.ArrayList;

@Configuration
public class SwaggerConfig {

    /**
     * 配置 Swagger Docket 的 bean实例
     *
     * @return Docket 的 bean实例
     */
    @Bean
    public Docket docket(Environment environment) {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .enable(true)
                .groupName("阿拉丁")
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.aladdin.swagger.controller"))
                //.paths(PathSelectors.ant("/aladdin/**"))
                .build();
    }

    /**
     * 配置 swagger 的信息:ApiInfo
     *
     * @return ApiInfo 的 bean实例
     */
    public ApiInfo apiInfo() {

        //作者信息
        Contact contact = new Contact("阿拉丁", "https://blog.csdn.net/weixin_52610802?type=blog", "coder_cong@163.com");

        return new ApiInfo("Aladdin的SwaggerAPI文档",
                "不负韶华,未来可期",
                "V1.0",
                "https://blog.csdn.net/weixin_52610802?type=blog",
                contact,
                "Apache 2.0",
                "http://www.apache.org/licenses/LICENSE-2.0",
                new ArrayList());
    }

    @Bean
    public Docket docket1() {
        return new Docket(DocumentationType.SWAGGER_2).groupName("分组1");
    }

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

    @Bean
    public Docket docket3() {
        return new Docket(DocumentationType.SWAGGER_2).groupName("分组3");
    }

}

模型类模块(Models)

  • Swagger 页面 Models 模块为实体类信息

  • 如果 Swagger 分组扫描的接口返回值存在实体类,则此实体类就会被扫描到该分组中

    1. 新建实体类

      public class User {
      
          private String username;
          private String password;
      
          ...
      }
      
    2. 增加返回值为 User 类的接口

      @RestController
      public class HelloController {
      
          @GetMapping("/hello")
          public String hello() {
              return "Hello";
          }
      
          @PostMapping("/user")
          public User user() {
              return new User("123", "qwe");
          }
      
      }
    3. 重启项目,访问 Swagger 页面,则会看见 Models 中加载了 User 实体类

文档注释

可使用 Swagger 注解为生成的 Api 在线文档添加注释信息

作用范围 API 使用位置
描述返回对象的意义 @ApiModel 用在返回对象类上
对象属性 @ApiModelProperty 用在出入参数对象的字段上
作用范围 API 使用位置
协议集描述 @Api 用于controller类上
协议描述 @ApiOperation 用在controller的方法上
Response集 @ApiResponses 用在controller的方法上
Response @ApiResponse 用在 @ApiResponses里边
非对象参数集 @ApiImplicitParams 用在controller的方法上
非对象参数描述 @ApiImplicitParam 用在@ApiImplicitParams的方法里边
  • @Api:用在controller上,对controller进行注释;

  • @ApiOperation:用在API方法上,对该API做注释,说明API的作用;

  • @ApiResponses:通常用来包含接口的一组响应注解,可以简单的理解为响应注解的集合声明;

  • @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息;

    • code:即httpCode,例如400;
    • message:信息,例如"请求参数没填好";

    即使只有一个@ApiResponse,也需要使用@ApiResponses包住。

  • @ApiImplicitParams:用来包含API的一组参数注解,可以简单的理解为参数注解的集合声明;

  • @ApiImplicitParam:用在 @ApiImplicitParams 注解中,也可以单独使用,说明一个请求参数的各个方面,该注解包含的常用选项有:

    属性 取值 作用
    paramType 查询参数类型
    path 以地址的形式提交数据
    query 直接跟参数完成自动映射赋值
    body 以流的形式提交 仅支持POST
    header 参数在request headers 里边提交
    form 以form表单的形式提交,仅支持POST
    dataType 参数的数据类型 只作为标志说明,并没有实际验证
    Long
    String
    name 接收参数名
    value 接收参数的意义描述
    required 参数是否必填
    true 必填
    false 非必填
    defaultValue 默认值代码
    1. form域中的值需要使用@RequestParam获取
    2. header域中的值需要使用@RequestHeader来获取
    3. path域中的值需要使用@PathVariable来获取
    4. body域中的值使用@RequestBody来获取,否则可能出错;而且如果paramType是body,name就不能是body,否则有问题,与官方文档中的 “If paramType is "body", the name should be "body" 不符。

Swagger Demo

https://gitee.com/caoguangcong/swagger-demo.git


部分示范代码

package com.aladdin.swagger.pojo;

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

@ApiModel("用户实体类")
public class User {

    @ApiModelProperty(value = "用户名", example = "123123", required = true)
    private String username;

    @ApiModelProperty(value = "密码", example = "aaa123", required = true)
    private String password;

    ...
}
package com.aladdin.swagger.controller;

import com.aladdin.swagger.pojo.User;
import io.swagger.annotations.*;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

@Api("Hello 控制类")
@RestController
public class HelloController {

    @ApiOperation("测试query")
    @ApiResponses({@ApiResponse(code = 1000, message = "操作成功"),
            @ApiResponse(code = 9999, message = "系统异常"),
            @ApiResponse(code = 8888, message = "权限不足")})
    @ApiImplicitParams({@ApiImplicitParam(paramType = "query", dataType = "String", name = "str", value = "字符串", required = true)})
    @GetMapping("/hello")
    public String hello(String str) {
        return "Hello: " + str;
    }

    @ApiOperation("测试path")
    @ApiImplicitParams({@ApiImplicitParam(paramType = "path", dataType = "Long", name = "id", value = "信息id", required = true)})
    @GetMapping("/hello2/{id}")
    public String hello2(@PathVariable("id") Long id) {
        return "Hello: " + id;
    }

    @ApiOperation("测试header")
    @ApiImplicitParams({@ApiImplicitParam(paramType = "header", dataType = "Long", name = "id", value = "信息id", required = true)})
    @GetMapping("/hello3")
    public String hello3(@RequestHeader("id") Long id) {
        return "Hello: " + id;
    }

    @ApiOperation("测试form")
    @ApiImplicitParams({ @ApiImplicitParam(paramType = "form", dataType = "Long", name = "id", value = "信息id", required = true) })
    @PostMapping(value = "/hello4", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public String hello4(@RequestParam("id") Long id) {
        return "Hello: " + id;
    }

    @ApiOperation("测试body")
    @ApiImplicitParams({@ApiImplicitParam(paramType = "body", dataType = "User", name = "user", value = "用户信息参数", required = true)})
    @PostMapping("/user")
    public User user(@RequestBody User user) {
        return user;
    }

}

总结

  1. 可通过 Swagger 给一些比较难理解的属性或者接口增加注释信息;
  2. 接口文档实时更新;
  3. 可以在线测试。

注意:出于安全考虑,在正式发布的时候,关闭 Swagger,同时也会节省运行内存。

MIT License Copyright (c) 2022 Aladdin Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

swagger简单演示 展开 收起
Java
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/caoguangcong/swagger-demo.git
git@gitee.com:caoguangcong/swagger-demo.git
caoguangcong
swagger-demo
swagger-demo
master

搜索帮助

Bbcd6f05 5694891 0cc6727d 5694891