Swagger强大的API文档工具

1.Swagger是什么?
Swagger 是一款RESTFUL接口的、基于YAML、JSON语言的文档在线自动生成、代码自动生成的工具。Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化RESTfu风格的web服务。
简单点来讲就是,swagger是一款可以根据restful风格生成的接口开发文档,并且支持做测试的一款中间软件。官网地址 https://swagger.io/
Swagger是一个流行的API开发框架,Swagger允许用户使用Swagger编辑器描述OAS 3.0 API(OpenAPI Specification,OAS),并使用Swagger UI可视化并自动生成OAS 3.0中定义的API文档。
Swagger 对整个API的开发周期都提供了相应的解决方案,是一个规范和完整的框架。包括API设计、API开发、API文档、API测试、API治理等,Swagger几乎支持所有语言。
1.1 swagger 和springfox的区别?
Swagger UI 允许用户使用Swagger编辑器描述OAS 3.0 API,并使用Swagger UI可视化并自动生成OAS 3.0中定义的API文档。
Springfox 用Spring构建自动的 JSON API文档的工具。
Swagger 是一种规范。
springfox-swagger 是基于 Spring 生态系统的该规范的实现。
springfox-swagger-ui 是对 swagger-ui 的封装,使得其可以使用 Spring 的服务。

2.为什么使用swagger?
现代化的研发组织架构中,一个研发团队基本包括了产品组、后端组、前端组、APP端研发、 测试组、 UI组等,各个细分组织人员各司其职,共同完成产品的全周期工作。如何进行组织架构内的有效高效沟通就显得尤其重要。其中,如何构建一份合理高效的接口文档更显重要。

2.1.对于后端开发人员来说:
(1) 不用再手写Wiki接口拼大量参数,避免手写错误
(2) 对代码侵入性低,采用全注解的方式,开发简单
(3) 方法参数名修改、新增、减少参数都可以直接生效,不用手动维护
(4) 缺点:增加了开发成本,写接口还得再写一套参数配置
2.2.对前端开发来说
(1) 后端只需要定义好接口,会自动生成文档,接口功能、参数一目了然
(2) 联调方便,如果出了问题,直接测试接口,实时检查参数和返回值,就可以快速定位是前端还是后端的问题
2.3.对于测试
(1) 但对于测试没有前端界面UI的功能,可以直接用它来测试接口
(2) 操作简单,不用了解具体代码就可以操作

  1. 常用的注解

注解

描述

@Api

修饰整个类,描述Controller的作用

@ApiOperation

描述一个类的方法,或者说一个接口

@ApiParam

单个参数描述

@ApiModel

用对象来接受参数

@ApiProperty

用对象来接收参数时,描述对象的一个字段

@ApiResponse

HTTP响应其中一个描述

@ApiResponses

HTTP响应整体描述

@@Apilgnore

使用该注解忽略这个API

@ApiError

发生错误返回的信息

@ApilmplictParam

一个请求参数

@ApilmplicitParams

多个请求参数

这里只收集了一部分注解

  1. 如何搭建一个swagger?
    4.1 Springfox与swagger的整合使用与关系
    swagger是一个流行的API开发框架,这个框架以“开放API声明”(OpenAPI Specification,OAS)为基础,对整个API的开发周期都提供了相应的解决方案,是一个非常庞大的项目(包括设计、编码和测试,几乎支持所有语言)。
    OAS本身是一个API规范,它用于描述一整套API接口,包括一个接口是GET还是POST请求啊,有哪些参数哪些header啊,都会被包括在这个文件中。它在设计的时候通常是YAML格式,这种格式书写起来比较方便,而在网络中传输时又会以json形式居多,因为json的通用性比较强。
    由于Spring的流行,Marty Pitt编写了一个基于Spring的组件swagger-springmvc,用于将swagger集成到springmvc中来。而springfox则是从这个组件发展而来,同时springfox也是一个新的项目,本文仍然是使用其中的一个组件springfox-swagger2。
    pringfox-swagger2依然是依赖OSA规范文档,也就是一个描述API的json文件,而这个组件的功能就是帮助我们自动生成这个json文件,我们会用到的另外一个组件springfox-swagger-ui就是将这个json文件解析出来,用一种更友好的方式呈现出来

4.2 Springboot集成Swagger
4.2.1 导入依赖

<!--swagger 2.9.2目前是最新版本较稳定-->
<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>

4.2.2 创建swagger配置类

package com.xr.springbootquartz.controller;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
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 springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author WuJia
 * @create 2019-1-3 19:16
 * 创建该API的基本信息(这些基本信息会展现在文档页面中)
 * 访问地址:http://127.0.0.1:8899/swagger-ui.html
 */
@EnableWebMvc
@EnableSwagger2
@Configuration
public class SwaggerConfig extends WebMvcConfigurationSupport{
    /**
     * 创建API应用
     * apiInfo() 增加API相关信息
     * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现,
     * 本例采用指定扫描的包路径来定义指定要建立API的目录。
     */
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com"))
                .paths(PathSelectors.any())
                .build();
    }
    /**
     * 创建该API的基本信息(这些基本信息会展现在文档页面中)
     * 访问地址:http://127.0.0.1:8899/swagger-ui.html
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("springboot集成swagger生成API文档")//标题
                .description("关于quartz的一些操作接口调用")//描述
                .contact(new Contact("WuJia", "", "2892940836@qq.com"))//作者信息
                .version("6.6.6")//版本号
                .build();
    }
}

4.2.3 SpringBoot集成Swagger2遇到异常:请求不到swagger-ui.html

APi 开放平台技术架构图 api开发工具_spring


APi 开放平台技术架构图 api开发工具_APi 开放平台技术架构图_02


这个错误,是因为静态资源路径映射问题导致。或者忘了在配置类加@EnableWebMvc

我们在访问http://localhost/swagger-ui.html时,这个swagger-ui.html相关的所有前端静态文件都在springfox-swagger-ui-2.9.2.jar里面。

解决方案如下:

package com.xr.springbootquartz.controller;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/js/**").addResourceLocations("classpath:/js/");
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

}

4.2.4 建一个Quartzcontroller类

package com.xr.springbootquartz.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xr.springbootquartz.job.ScheduledJob;
import com.xr.springbootquartz.job.SchedulerManager;
import com.xr.springbootquartz.model.Ttrigger;
import com.xr.springbootquartz.service.TriggerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author:
 * @create: 2019-10-30 15:58
 **/

@Api(value="aaaaaaa",description="Quartz的相关信息接口")
@Controller
@RestController
public class QuartzController {
    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;

    @Autowired
    private TriggerService triggerService;
    //获得所有的作业任务
    @ApiOperation(value="获取所有quartz定时任务",notes="获取所有job,无需参数", httpMethod = "POST")
    @RequestMapping("/getList")
    public String getList(){
        List<Ttrigger> list=triggerService.getTrigger();
        String jso = JSON.toJSONString(list);
        String UserJson = "{\"code\":0,\"msg\":\"\",\"count\":"+1+",\"data\":"+jso+"}";
        return UserJson;
    }
    //测试更新
    @ApiOperation(value="测试更新",notes="更新任务,无需", httpMethod = "POST")
    @RequestMapping("/start")
    public String start(){
        triggerService.refreshTrigger();
        return "更新成功";
    }
       //新增作业
    @ApiOperation(value="新增任务",notes="需要trigger,需要参数", httpMethod = "POST")
    @RequestMapping("/addJob")
    public String addJob(Ttrigger ttrigger){
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        ttrigger.setAddTime(df.format(new Date()));// new Date()为获取当前系统时间
        ttrigger.setState("1");
        triggerService.add(ttrigger);
        triggerService.refreshTrigger();
        System.out.println(ttrigger);
        return "新增成功";
    }
    //暂停单个作业
    @ApiOperation(value="暂停单个作业",notes="需要jobName和group,需要参数", httpMethod = "POST")
    @RequestMapping("/zanting")
    public String stop(Ttrigger ttrigger) throws SchedulerException {
     /*   System.out.println(jobName+".."+group);*/
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = new JobKey(ttrigger.getJobName(),ttrigger.getGroup());
       /* System.out.println(jobKey);
        System.out.println("j:  "+new JobKey("com.xr.springbootquartz.job.TestTask2","default"));*/
        scheduler.pauseJob(jobKey);
        return "暂停成功";
    }
//批量暂停
@ApiOperation(value="批量餐厅任务",notes="需要jobName和group,需要参数", httpMethod = "POST")
@RequestMapping("/moreZanting")
    public void moreZanting(String test) throws SchedulerException {
        //json转对象
        List<Ttrigger> ttriggerList1 = JSON.parseArray(test, Ttrigger.class);
        for(Ttrigger ttrigger : ttriggerList1){ // Exception
            stop(ttrigger);
        }
    }

    /**
     * 恢复单个定时任务
     *

     * @throws SchedulerException
     */
    @ApiOperation(value="恢复单个任务",notes="需要jobName和group,需要参数", httpMethod = "POST")
    @RequestMapping("/huifu")
    public void resumeJob(Ttrigger ttrigger)
            throws SchedulerException
    {
        /*System.out.println(ttrigger.getJobName()+"恢复任务"+ttrigger.getGroup());
        System.out.println(getType(ttrigger.getJobName()));
        System.out.println(getType("com.xr.springbootquartz.job.TestTask2"));
*/
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey triggerKey = new JobKey(ttrigger.getJobName(),ttrigger.getGroup());
      /*  System.out.println(new JobKey(ttrigger.getJobName(),ttrigger.getGroup()));
        System.out.println("j:  "+new JobKey("com.xr.springbootquartz.job.TestTask2","default"));*/
        scheduler.resumeJob(triggerKey);
    }
  //批量恢复作业
    @ApiOperation(value="批量恢复任务",notes="需要jobName和group,需要参数", httpMethod = "POST")
    @RequestMapping("/moreHuifu")
    public void test(String test) throws SchedulerException {
        //json转对象
        List<Ttrigger> ttriggerList1 = JSON.parseArray(test, Ttrigger.class);
        for(Ttrigger ttrigger : ttriggerList1){ // Exception
            resumeJob(ttrigger);
        }
    }
    //删除单个作业
    @ApiOperation(value="删除单个任务",notes="需要jobName和group,需要参数", httpMethod = "POST")
    @RequestMapping("/deleteJob")
    public void deleteJob(Ttrigger ttrigger)
            throws SchedulerException
    {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobKey jobKey = new JobKey(ttrigger.getJobName(), ttrigger.getGroup());
        scheduler.deleteJob(jobKey);
    }
    @ApiOperation(value="批量删除任务",notes="需要jobName和group,需要参数", httpMethod = "POST")
    @RequestMapping("/moreDelete")
    public void moreDelete(String test)
            throws SchedulerException
    {
        /*List<SubTrade> subTrades = JSON.parseArray(json.getString("subTradeList"), SubTrade.class);*/
        //json转对象
        List<Ttrigger> ttriggerList1 = JSON.parseArray(test, Ttrigger.class);
        for(Ttrigger ttrigger : ttriggerList1){ // Exception
            deleteJob(ttrigger);
        }
    }


}

4.2.5 主程序启动后访问http://localhost:8899/swagger-ui.html

我设置的端口号是8899

可看到如下页面

注意controller类自己建

APi 开放平台技术架构图 api开发工具_APi 开放平台技术架构图_03


点击其中一个接口页面如下

APi 开放平台技术架构图 api开发工具_APi 开放平台技术架构图_04


点击try it out 进入接口调试,有参数输入参数,无参数直接执行 点击excute执行获得json数据如下

APi 开放平台技术架构图 api开发工具_API_05