一文学会Swagger2

Swagger2

目录 介绍 搭建及使用 常用注解介绍 Api文档导出

Swagger2介绍

官话

swagger2 是一个规范和完整的框架,用于生成、描述、调用和可视化Restful风格的web服务。

白话

现在很多项目都是前后端分离的,后端一般都需要自己手写维护一个后台api接口文档,提供给前台看,比较麻烦,而且还存在交流不及时的问题,这个工具可以实现自动生成一个Restful Api在线文档,可以对接口进行解释及测试,同样还支持在线文档导出为本地文档

LOGO

image-20201103222913991

官网

https://swagger.io

github

https://github.com/swagger-api

作用

自动生成接口文档,节省维护成本

image-20201104094912766

接口文档内可以实现在线接口测试

image-20201104095333054
image-20201104095603721

Swagger2搭建

  • 使用springboot整合Swagger2案例

  • 引入依赖

    <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>
    
  • 在启动类上添加注解@EnableSwagger2

    @EnableSwagger2
    public class Application {
        public static void main(String[] args) {
            SpringApplication.run(BlogApplication.class, args);
        }
    
    }
    
  • 编写Swagger2配置类Swagger2Config,进行相关配置

    @Configuration
    @EnableSwagger2
    public class Swagger2Config {
        @Bean
        public Docket createRestApi() {
            return new Docket(DocumentationType.SWAGGER_2)
                //调用下面写的配置api文档的基本信息方法
                .apiInfo(this.apiInfo())
                //配置映射路径前缀的意思,假如配置为"/blog",后台requestmapping接口为/user/getById那么,访问路径就变成了/blog/user/getById
                .pathMapping("/")
                //创建api选择器,用于选择api
                .select()
                //apis配置api所在位置,下面apis的参数
                //any():扫描全部
                //none():全部不扫描
                //RequestHandlerSelectors.basePackage("com.xx.xx.controller")配置捕获请求所在的package
                //RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)配置有ApiOperation注解的方法才生成接口文档
                //RequestHandlerSelectors.withClassAnnotation(RestController.class)配置有RestController注解的类中的方法生成接口文档
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)
                //路径过滤
                //ant:指定路径
                //any:过滤全部
                //none:全部不过滤
                //regex:使用正则过滤
                .paths(PathSelectors.any())
                .build();
        }
        //配置接口文档的基本信息
        private ApiInfo apiInfo(){
            return new ApiInfoBuilder()
                    .title("api文档标题	eg XX系统接口api")
                    .description("api文档描述 eg 提供XX功能的restful接口")
                    .version("版本号 eg 1.0.0")
                    .termsOfServiceUrl("服务条款URL")
                    .license("许可证")
                    .licenseUrl("许可证URL")
                    .extensions("扩展信息,参数为List<VendorExtension> extensions")
                    .build();
        }
    }
    
  • 编写Result返回结果类,也可以不用

    public class SwagResult {
        //返回状态	eg,success,error
        private String status;
        //存放返回数据
        private Object result;
        public String getStatus() {
            return status;
        }
        public void setStatus(String status) {
            this.status = status;
        }
        public Object getResult() {
            return result;
        }
        public void setResult(Object result) {
            this.result = result;
        }
        public void success(Object result){
            this.status = "success";
            this.result = result;
        }
        public void error(Object result){
            this.status = "error";
            this.result = result;
        }
    }
    
  • 编写控制器,并添加相应注解,目前先简单看一下代码,后面有各个注解的详细解释

    @RestController
    @Api(value = "管理用户信息")
    @RequestMapping("/blog/user")
    public class UserController {
        @Autowired
        private UserService userService;
        @ApiOperation(value="得到全部用户", notes="获取全部用户")
        @GetMapping("/getAll")
        public SwagResult getAll(){
            SwagResult result = new SwagResult();
            try{
                result.success(userService.getList());
            }catch (Exception e){
                result.error(e.getClass().getName() + ":" + e.getMessage());
                e.printStackTrace();
            }
            return result;
        }
    }
    
  • 在静态资源配置中将swagger2-ui.html映射到classpath:/META-INF/resouces/

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
            registry.addResourceHandler("swagger-ui.html")
                    .addResourceLocations("classpath:/META-INF/resources/");
        }
    }
    
  • 配置完成,在浏览器打开localhost:端口号/swagger-ui.html

    image-20201104094912766

常用注解介绍

说明:本次在介绍参数时,较低版本就被遗弃的参数在此不再介绍

  • @Api

    使用位置:用在请求类上,一般为controller上

    作用:表示对类的说明

    参数

    参数类型默认值描述
    tagsString[]“”说明该类的作用,非空时会覆盖value值
    valueString{""}描述类的作用,基本不用,tags就够了
    producesString“”设置MIME类型(output)列表,eg“application/json, application/xml”
    consumesString“”设置MIME类型(input)列表,eg“application/json, application/xml”
    protocolsString“”设置特定协议,eg http,https,ws,wss
    authorizationsauthorizations[]{@Authorization("")}获取授权列表
    hiddenbooleanfalse隐藏设置,参数为true时则在api文挡中隐藏

    总结

    一般就用tags参数,其他的除非特殊需要

    案例

    @RestController
    @Api(tags = "用户信息管理Controller")
    @RequestMapping("/user")
    public class UserController {
        ...
    }
    

    没用tags

    image-20201104103804906

    使用tags

    image-20201104103734685

  • @ApiOperation

    使用位置:用在类的请求方法上,一般就是controller内的请求方法

    作用:对方法进行说明

    参数

    参数类型默认值描述
    valueString“”描述方法的作用
    notesString“”方法的备注说明
    tagsString[]{""}方法描述,非空时将覆盖value值
    responseClass<?>Void.class响应类型
    responseContainerString“”返回对象容器的声明
    responseReferenceString“”指定对响应类型的引用
    httpMethodString“”请求方式,eg get,post
    nicknameString“”第三方工具唯一标识
    producesString“”设置MIME类型(output)列表,eg“application/json, application/xml”
    consumesString“”设置MIME类型(input)列表,eg“application/json, application/xml”
    protocolsString“”设置特定协议,eg http,https,ws,wss
    authorizationsauthorizations[]{@Authorization("")}获取授权列表
    hiddenbooleanfalse隐藏设置,参数为true时则在api文档中隐藏
    responseHeadersResponseHeader[]{@ResponseHeader( name = “”, response = Void.class )};响应头列表
    codeint200HTTP状态码
    extensionsExtension[]{@Extension( properties = {@ExtensionProperty( name = “”, value = “” )} )};扩展属性列表

    总结

    常用参数为value和notes,value对方法进行简单说明,notes进行补充,其他参数根据需要使用

    @ApiOperation和@Api都有value和tags参数,但是常用参数不同

    @ApiOperation用value和notes进行方法说明

    @Api使用tags进行类说明

    案例

    @ApiOperation(value="获取全部用户列表", notes="不需要参数")
    @GetMapping("/getAll")
    public SwagResult getAll(){
        SwagResult result = new SwagResult();
        try{
            result.success(userService.getList());
        }catch (Exception e){
            result.error(e.getClass().getName() + ":" + e.getMessage());
            e.printStackTrace();
        }
        return result;
    }
    

    使用效果,没有使用,则没有方法说明

    image-20201104110400834

  • @ApiImplicitParam

    使用位置:直接用在请求方法上,或用在请求方法上@ApilmplicitParams注解中

    作用:对一个请求参数进行说明

    参数

    参数类型默认值描述
    nameString“”参数名,一般和解释的方法参数一致
    valueString参数的说明
    defaultValueString“”参数默认值
    requiredbooleanfalse是否必须传参
    accessString“”允许api文档中过滤参数
    allowMultiplebooleanfalse是否
    dataTypeString“”参数数据类型,eg Integer
    dataTypeClassClass<?>Void.class参数数据类型类对象
    paramTypeString“”参数的类型
    header获取时使用@RequestHeader
    query获取时使用@RequestParam
    path获取时使用@PathVariable
    body
    form
    exampleString“”单个示例
    examplesExampleExample({@ExampleProperty( mediaType = “”, value = “” )})参数示例,仅适用于BodyParameters
    typeString“”
    formatString“”
    allowEmptyValuebooleanfalse是否允许参数值为空
    readOnlybooleanfalse参数是否只读
    collectionFormatString“”

    总结

    常用参数为name,value,required,paramType,dataType,defaultValue等

    案例

    @ApiOperation(value="根据id获取用户信息", notes="输入String参数id来获取用户信息")
    @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "String")
    @GetMapping("/getById")
    public SwagResult getById(@RequestParam("id") String id){
        SwagResult result = new SwagResult();
        try{
            result.success(userService.getById(id));
        }catch (Exception e){
            result.error(e.getClass().getName() + ":" + e.getMessage());
            e.printStackTrace();
        }
        return result;
    }
    

    效果

    image-20201104114156274

  • @ApiImplicitParams

    使用位置:直接用在请求发方法上

    作用:多个参数进行描述

    参数

    参数类型默认值描述
    valueApiImplicitParam[]ApiImplicitParam列表

    案例

    @ApiOperation(value="根据姓名和邮件查询用户信息", notes="输入String的anme和email来获取用户信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "name", value = "用户姓名", required = true, dataType = "String")
                        ,@ApiImplicitParam(name = "email", value = "用户邮箱", required = true, dataType = "String")})
    @GetMapping("/getByNameEmail")
    public SwagResult getByNameEmail(@RequestParam("name") String name,@RequestParam("email") String email){
        SwagResult result = new SwagResult();
        try{
            result.success(userService.getByNameEmail(name, email));
        }catch (Exception e){
            result.error(e.getClass().getName() + ":" + e.getMessage());
            e.printStackTrace();
        }
        return result;
    }
    

    效果

    image-20201104120201866

  • @ApiParam

    使用位置:用在请求方法的括号中被描述参数的前面

    作用:参数的简要说明

    参数

    参数类型默认值描述
    nameString“”参数名,一般和解释的方法参数一致
    valueString参数的说明
    defaultValueString“”参数默认值
    requiredbooleanfalse是否必须传参
    accessString“”允许api文档中过滤参数
    allowMultiplebooleanfalse是否
    hiddenbooleanfalse参数是否隐藏
    exampleString“”单个示例
    examplesExampleExample({@ExampleProperty( mediaType = “”, value = “” )})参数示例,仅适用于BodyParameters
    typeString“”
    formatString“”
    allowEmptyValuebooleanfalse是否允许参数值为空
    readOnlybooleanfalse参数是否只读
    collectionFormatString“”

    总结

    因为在函数内,所以一般就只会用几个参数不会太多,太多的话可以使用@ApiImplicitParam

    案例

    @ApiOperation(value="根据姓名和邮件查询用户信息", notes="输入String的anme和email来获取用户信息")
    @GetMapping("/getByNameEmail")
    public SwagResult getByNameEmail(
        @ApiParam(name = "name", value = "用户姓名", required = true) String name
        ,@ApiParam(name = "email", value = "用户邮箱", required = true) String email){
        SwagResult result = new SwagResult();
        try{
            result.success(userService.getByNameEmail(name, email));
        }catch (Exception e){
            result.error(e.getClass().getName() + ":" + e.getMessage());
            e.printStackTrace();
        }
        return result;
    }
    

    效果

    image-20201104125541459

  • @ApiResponse

    使用位置:用在请求的方法上,一般放在@ApiResponses里使用

    作用:表示一个响应信息,一般用来描述错误信息

    参数

    参数类型默认值描述
    codeintHTTP状态码
    messageString信息
    responseClass<?>Void.class抛出异常的类
    referenceString“”响应的引用类型
    responseHeadersResponseHeader[]{@ResponseHeader( name = “”, response = Void.class )}响应头列表
    responseContainerString“”响应容器类型
    examplesExample@Example({@ExampleProperty( value = “”, mediaType = “” )})示例

    案例1,单独使用@ApiResponse注解

    @ApiOperation(value="根据id获取用户信息", notes="输入String参数id来获取用户信息")
    @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "String")
    @ApiResponse(code=404,message="请求路径没有或页面跳转路径不对")
    @GetMapping("/getById")
    public SwagResult getById(@RequestParam("id") String id){
        SwagResult result = new SwagResult();
        try{
            result.success(userService.getById(id));
        }catch (Exception e){
            result.error(e.getClass().getName() + ":" + e.getMessage());
            e.printStackTrace();
        }
        return result;
    }
    

    效果,根据结果发现并没有起作用,404 Not Found是默认的值,没有变成我们写的message信息

    image-20201104131641388

    案例2,将@ApiResponse注解放在@ApiResponses

    @ApiOperation(value="根据id获取用户信息", notes="输入String参数id来获取用户信息")
    @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "String")
    @ApiResponses({
        @ApiResponse(code=404,message="请求路径没有或页面跳转路径不对")
    })
    @GetMapping("/getById")
    public SwagResult getById(@RequestParam("id") String id){
        SwagResult result = new SwagResult();
        try{
            result.success(userService.getById(id));
        }catch (Exception e){
            result.error(e.getClass().getName() + ":" + e.getMessage());
            e.printStackTrace();
        }
        return result;
    }
    

    效果,结果发现==@ApiResponse注解放在@ApiResponses里才起作用==

    image-20201104132055973

  • @ApiResponses

    使用位置:用在请求方法上

    作用:描述一组响应信息

    参数

    参数类型默认值描述
    valueApiResponse[]ApiResponse列表

    案例见@ApiResponse注解的案例

  • @ApiModel

    使用位置:用于响应类或参数类上,一般为Entity或者DTO,一般在响应数据当好是一个类的时候或者@ApiImplicitParam无法或过于复杂描述的时候

    作用:描述响应类的信息

    参数

    参数类型默认值描述
    valueString“”描述响应类
    descriptionString“”具体描述响应类的信息作用等
    parentClass<?>Void.class响应类负类的类对象
    discriminatorString“”鉴别器
    subTypesClass<?>[]{}
    referenceString“”响应类的引用类型

    总结

    一般就使用value和description进行描述响应类

    案例

    @ApiModel(value = "返回结果",description = "用于存储请求结果的状态及返回数据")
    public class SwagResult {
    	...
    }
    
  • @ApiModelProperty

    使用位置:用在@ApiModel注解的类的属性上

    作用:对属性进行描述

    参数

    参数类型默认值描述
    valueString属性参数的说明
    nameString“”属性参数名
    allowableValuesString“”限制参数可以接收的值
    以逗号分隔的列表eg “1,2”
    范围值
    最大/最小值
    accessString“”允许api文档中过滤参数
    notesString“”属性参数备注信息
    dataTypeString“”属性参数类型
    requiredbooleanfalse是否必须有
    positionint0设置不同数值,实现调整参数在api文档中的位置
    hiddenbooleanfalse参数是否隐藏
    exampleString“”单个示例
    allowEmptyValuebooleanfalse是否允许参数值为空
    readOnlybooleanfalse参数是否只读
    extensionsExtension[]{@Extension( properties = {@ExtensionProperty( name = “”, value = “” )} )}扩展信息列表

案例

  @ApiModel(value = "返回结果",description = "用于存储请求结果的状态及返回数据")
  public class SwagResult {
      @ApiModelProperty(value = "状态",notes = "success表示成功,error表示失败",required = true)
      private String status;
      @ApiModelProperty(value = "结果",notes = "用于存储请求结果数据",required = true)
      private Object result;
      public String getStatus() {
          return status;
      }
      public void setStatus(String status) {
          this.status = status;
      }
      public void success(Object result){
          this.status = "success";
          this.result = result;
      }
      public void error(Object result){
          this.status = "error";
          this.result = result;
      }
      public Object getResult() {
          return result;
      }
      public void setResult(Object result) {
          this.result = result;
      }
  }

关闭Swagger2方法

当项目上线时需要关闭Swagger2,关闭方法如下

在Swagger2Config中进行关闭

@Configuration
@EnableSwagger2
public class Swagger2Config {
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
            .apiInfo(this.apiInfo())
            .pathMapping("/")
            .select()
            .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)
            .paths(PathSelectors.any())
            .build().enable(false);	//在build()后加enable(false)进行关闭
    }
    //配置接口文档的基本信息
    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("api文档标题	eg XX系统接口api")
                .description("api文档描述 eg 提供XX功能的restful接口")
                .version("版本号 eg 1.0.0")
                .termsOfServiceUrl("服务条款URL")
                .license("许可证")
                .licenseUrl("许可证URL")
                .extensions("扩展信息,参数为List<VendorExtension> extensions")
                .build();
    }
}

关闭效果
微信图片_20201104144706

Api文档导出

Api文档导出官方支持三种格式:markdown、asciidoc、confluence

导入pom依赖

<dependency>
    <groupId>io.github.swagger2markup</groupId>
    <artifactId>swagger2markup</artifactId>
    <version>1.3.3</version>
</dependency>

配置repositories

<repositories>
    <repository>
        <id>spring-libs-milestone</id>
        <url>https://repo.spring.io/libs-milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

<pluginRepositories>
    <pluginRepository>
        <id>spring-plugins-release</id>
        <url>https://repo.spring.io/plugins-release</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

实现代码如下

调用Swagenerator之前需要先运行application主程序

public class SwagGenerator {
    //生成AsciiDocs格式文档
    public void generateAsciiDocs() throws Exception {
        Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL("http://127.0.0.1:8080/v2/api-docs"))
                .withConfig(config)
                .build()
                .toFolder(Paths.get("./docs/asciidoc/generated"));
    }

    //生成Markdown格式文档
    public void generateMarkdownDocs() throws Exception {
        Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.MARKDOWN)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))
                .withConfig(config)
                .build()
                .toFolder(Paths.get("./docs/markdown/generated"));
    }
    //生成Confluence格式文档
    public void generateConfluenceDocs() throws Exception {
        Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))
                .withConfig(config)
                .build()
                .toFolder(Paths.get("./docs/confluence/generated"));
    }

    //生成AsciiDocs格式的一个文档
    public void generateAsciiDocsToFile() throws Exception {
        Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.ASCIIDOC)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))
                .withConfig(config)
                .build()
                .toFile(Paths.get("./docs/asciidoc/generated/all"));
    }

    //成Markdown格式的一个文档
    public void generateMarkdownDocsToFile() throws Exception {
        Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
                .withMarkupLanguage(MarkupLanguage.MARKDOWN)
                .withOutputLanguage(Language.ZH)
                .withPathsGroupedBy(GroupBy.TAGS)
                .withGeneratedExamples()
                .withoutInlineSchema()
                .build();

        Swagger2MarkupConverter.from(new URL("http://localhost:8080/v2/api-docs"))
                .withConfig(config)
                .build()
                .toFile(Paths.get("./docs/markdown/generated/all"));
    }
    public static void main(String[] args) throws Exception {
        SwagGenerator generator = new SwagGenerator();
        generator.generateMarkdownDocsToFile();
    }
}

导出结果

image-20201104165238001

markdown格式

image-20201104165327064

asciidoc格式

image-20201104170034876

参考链接

https://www.hellojava.com/a/59418.html
https://cloud.tencent.com/developer/article/1332445

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值