Swagger,好用的API管理神器(swagger学习简单总结)

来源:互联网 发布:十大网络主播评选结果 编辑:程序博客网 时间:2024/06/11 13:40

一、swagger简介

1.1. swagger是什么?

THE WORLD’S MOST POPULAR API TOOLING
Swagger is the world’s largest framework of API developer tools for the OpenAPI Specification(OAS), enabling development across the entire API lifecycle, from design and documentation, to test and deployment.

1.2. swagger能做什么?
swagger能通过与spring的整合,进而实现服务的api呈现及在线调用。

1.3.意义
1)传统的开发模式虽然也是前后台开发人员分开工作,但是如果前台开发人员想对其开发的功能在浏览器或者移动端进行测试,除非自己伪造一系列假数据,否则就需要与后台人员沟通,需要后台开发人员为其提供相应的web服务,这样一来前后台的工作就耦合在了一起。swagger的存在可以很好的将前后台工作区分开。前台开发人员无需关心后台数据如何处理,他只关心返回的数据格式是否满足其需求,通过swagger随时可以进行测试,无需与后台人员保持高频的沟通。而后台人员无需时时为前台人员提供web服务进行测试,他只需要将数据计算并组装为前台人员所需的格式即可,其他的交给swagger就行了。这样一来就降低了前后台开发人员的工作耦合程度。
2)服务端修改代码后,无需手动更新接口文档,通过swagger发布后,即为最新的服务接口文档。

二、swagger与springmvc整合

2.1如何整合?
①首先需要搭建一套springmvc的环境。简单描述如下:
1)创建maven项目,向pom文件中添加如下的依赖描述:

<dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-web</artifactId>    <version>4.3.6.RELEASE</version></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-webmvc</artifactId>    <version>4.3.6.RELEASE</version></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-aspects</artifactId>    <version>4.3.6.RELEASE</version></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-orm</artifactId>    <version>4.3.6.RELEASE</version></dependency><dependency>    <groupId>org.aspectj</groupId>    <artifactId>aspectjrt</artifactId>    <version>1.6.12</version></dependency>

2)在WEB-INF中新增springmvc-servlet.xml文件,基本内容如下:

<?xml version="1.0" encoding="UTF-8"?>        <beans xmlns="http://www.springframework.org/schema/beans"                          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                          xmlns:mvc="http://www.springframework.org/schema/mvc"                        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">      </beans>

3)在resource目录下新增applicationContext.xml文件,基本内容如下:

<?xml version="1.0" encoding="UTF-8"?>        <beans xmlns="http://www.springframework.org/schema/beans"                          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"                          xmlns:context="http://www.springframework.org/schema/context"                      xmlns:mvc="http://www.springframework.org/schema/mvc"                        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd                       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd                       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd                       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd                    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">    <mvc:annotation-driven/>    <context:component-scan base-package="earl.swagger"></context:component-scan>    <context:annotation-config></context:annotation-config></beans>

4)向web.xml文件中添加如下内容:

<?xml version="1.0" encoding="UTF-8"?>          <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"           xmlns:mvc="http://www.springframework.org/schema/mvc"          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">          <listener>              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>          </listener>          <context-param>              <param-name>contextConfigLocation</param-name>              <param-value>classpath:applicationContext.xml</param-value>          </context-param>          <servlet>              <servlet-name>springmvc</servlet-name>              <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>              <init-param>                  <param-name>contextConfigLocation</param-name>                  <param-value>/WEB-INF/springmvc-servlet.xml</param-value>              </init-param>              <load-on-startup>1</load-on-startup>        </servlet>          <servlet-mapping>              <servlet-name>springmvc</servlet-name>              <url-pattern>/*</url-pattern>        </servlet-mapping>  </web-app>

至此,一套springmvc的项目已经搭建完成。

②整合swagger到springmvc中
1)从github上下载swagger-ui的项目文件,并将其dist目录下的文件复制到WEB-INF下的swagger目录下。出于安全考虑,将swagger的静态资源放置在了WEB-INF下,那么外部就无法直接访问,所以还需要在springmvc配置文件中加入相应的映射,才能在外部访问到swagger的资源文件。添加如下配置到springmvc-servlet.xml中:
<mvc:resources mapping="/swagger/**" location="/WEB-INF/swagger/"/>

2)在pom文件中添加如下配置,引入与swagger整合的jar包。

<dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-swagger2</artifactId>    <version>2.4.0</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-databind</artifactId>    <version>2.6.4</version></dependency>

3)新增swagger的配置文件,有了该文件,才可以将相关的配置进行扫描。如下:

@Configuration@EnableSwagger2public class ApiConfig {    @Bean    public Docket getApiInfo() {        return new Docket(DocumentationType.SWAGGER_2)        .select()  // 选择那些路径和api会生成document        .apis(RequestHandlerSelectors.any()) // 对所有api进行监控        .paths(PathSelectors.any()) // 对所有路径进行监控        .build().apiInfo(apiInfo());    }    private ApiInfo apiInfo() {        ApiInfo info = new ApiInfo(        "swagger 测试",//标题        "测试",//描述        "0.1",//版本        "http://blog.csdn.net/EarlYuan",//服务条款的url        new Contact("EarlYuan", "www.google.com", "earlyuan@163.com"),        "",//版本许可        ""//版本许可url        );        return info;    }}

4)在对外发布服务的controller中进行如下注解的添加,从而实现服务API的对外暴露展示。

@Controller@RequestMapping(value = "/demo", consumes = "application/json", produces = "application/json")@Api(value = "Demo", description = "swagger操作")public class DemoController {    @ApiOperation(value = "查询服务", notes = "查询", response = ApiResult.class, httpMethod = "POST")    @RequestMapping(value = "query", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")    @ResponseBody    public ApiResult query() {        ApiResult result = new ApiResult();        result.setStatus("ok");        result.setResult("我是结果");        return result;    }}

5)修改swagger目录下的index.html中的url,将其修改为当前项目的访问路径。至此swagger整合就已完成。

6)浏览器访问,可以看到API文档输出。点击try it out,可以看到返回结果。

2.2参数传递:
1)url传参:
方式一:参数直接拼接在url中,通过注解@PathVariable在服务端可以接收到该参数。如下:

@ApiOperation(value = "查询服务", notes = "根据id查询", response = ApiResult.class, httpMethod = "POST")@RequestMapping(value = "query/{id}", method = RequestMethod.POST, consumes = "application/json", produces = "application/json;charset=UTF-8")@ResponseBodypublic ApiResult queryById(@ApiParam(required = true, name = "id", value = "唯一标识") @PathVariable String id) {    ApiResult result = new ApiResult();    result.setStatus("ok");    result.setResult("我是根据id查询出来的结果");    return result;}

方式二:不在URL中拼接参数,而是通过标签来设置,这样的话,会生成类似于这样的请求地址http://localhost:8080/swagger-demo/demo/add?request_token=666
如果需要在controller中获取请求参数,那么就可以使用request来获取(需要在web.xml中配置listener:org.springframework.web.context.request.RequestContextListener) 将注解@ApiImplicitParam的type设置为query,其他不变。定义全局变量@Autowired private HttpServletRequest request,调用request.getParameter方法获取请求参数。

2)请求体传参:参数通过请求体传递到服务端。由于restful形式的服务通常以json来传递数据,所以通过请求体传参就很灵活。可以传递bean,也可以传递json对象。但是此处有一个问题就是,只有使用bean作为载体时,生成的swagger界面上才会有该参数的详细介绍,通过json等对象传递时,由于没有指定属性是何含义,因此swagger不能够反射回去得到相应的属性解释。所以为了swagger页面便于阅读,我们还是将每一个不同的请求参数都作为一个单独的bean,这样生成的swagger界面对于服务调用者来说就更为友好。如下所示:

@ApiOperation(value = "新增服务", notes = "新增", response = ApiResult.class, httpMethod = "POST")@RequestMapping(value = "add", method = RequestMethod.POST)@ResponseBodypublic ApiResult add(@RequestBody @ApiParam(name = "news", value = "news", required = true) News news) {    System.out.println(news);    ApiResult result = new ApiResult();    result.setStatus("ok");    result.setResult("新增成功");    return result;}

参数News可以有如下定义:

@ApiModel(value = "新闻", description = "news")public class News {    @ApiModelProperty(name = "id", value = "id", notes = "唯一标识")    private String id;    @ApiModelProperty(name = "标题", value = "title", notes = "标题")    private String title;    @ApiModelProperty(name = "内容", value = "content", notes = "内容")    private String content;    @ApiModelProperty(name = "时间", value = "time", notes = "时间")    private String time;    getter and setter...}

3)请求头传参
因为使用的restful形式的服务,所以通常使用json来传递数据。在放方法定义上添加注解如下: @ApiImplicitParams({@ApiImplicitParam(name=”request_token”,value=”request_token”,required=true,paramType=”header”,dataType=”String”)}) 这样生成的服务就需要在请求头中带上request_token属性,可以从request中获取到request_token。

三、swagger注解详解:
1.@Api
用在类上,说明该类的作用
@Api(value = “Demo”, description = “swagger操作”)

2.@ApiOperation
用在方法上,说明方法的作用
@ApiOperation(value = “查询服务”, notes = “根据id查询”, response = ApiResult.class, httpMethod = “POST”)

3.@ApiImplicitParams
用在方法上包含一组参数说明

4.@ApiImplicitParam
用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
paramType:参数放在哪个地方
header–>请求参数的获取:@RequestHeader
query–>请求参数的获取:@RequestParam
path(用于restful接口)–>请求参数的获取:@PathVariable
body(不常用)
form(不常用)
name:参数名
dataType:参数类型
required:参数是否必须传
value:参数的意思
defaultValue:参数的默认值

常与ApiImplicitParam注解一起使用。
@ApiImplicitParams({ @ApiImplicitParam(name = “id”, value = “唯一id”, required = true, dataType = “Long”, paramType = “path”), })

5.@ApiResponses
用于表示一组响应

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

@ApiResponses(value = {
@ApiResponse(code = 400, message = “No Name Provided”)
})

7.@ApiModel
描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)
@ApiModel(value = “用户实体类”)

8.@ApiModelProperty
描述一个model的属性
@ApiModelProperty(name = “id”, value = “id”, notes = “唯一标识”)

四、swagger配置类详解
swagger的配置类除了Docket之外还有多种写法,例如SwaggerSpringMvcPlugin,但是相较于Docket来说,还是略逊一筹。其使用的多为非swagger官方的开发包进行配置,且配置不如Docket方便。 Docket提供多种过滤机制,可供用户对暴露的服务做到精确的发布控制。
API级别: 通过RequestHandlerSelectors提供的方法,可以控制到包,类,方法。
PATH级别: 通过PathSelector提供的方法,可以对服务发布的访问路径进行控制。

@Beanpublic Docket getApiInfo(){    Arraylist<ResponseMessage> responseMessages=new ArrayList<>();     responseMessages.add(new ResponseMessageBuilder().code(500).message("服务端500错误").reponseModel(new ModelRef("Error").build()));     ResponseMessageBuilder().code(404).message("服务端404错误").reponseModel(new ModelRef("NotFound").build()));     return new Docket(DocumentationType.SWAGGER_2).    useDefaultResponseMessage(false).globalResponseMessage(RequestMethod.GET,reponseMessages)     .select()//选择哪些路径和API会生成document     .apis(RequestHandlerSelectors.any())//对所有API进行监控     //.apis( RequestHandlerSelectors.basePackage("earl.swagger.controller.other") )    //对定义的包下的api进行监控     //.apis( RequestHandlerSelectors.withMethodAnnotation(Deprecate.class) )//对在方法上加了相关注解的api进行监控     //.apis( RequestHandlerSelectors.withClassAnnotation(Component.class) )//对在类上上加了相关注解的api进行监控     //.apis( RequestHandlerSelectors.none() )//不对api进行监控     .paths(PathSelectors.any())//对所有路径进行监控     //.paths( PathSelectors.regex("/demo2/query.*") )//对相匹配的路径进行监控     //.paths( PathSelectors.none() )//不对路径进行监控     .bulid.apiInfo(apiInfo()); } 

通过对RequestHandlerSelectors和 PathSelectors的设置,可以对需要发布的api进行控制。但是需要注意的是,即使通过相关配置过滤了某些服务,这些服务不会在浏览器中显示,但是这些服务依旧存在,通过http工具依旧可以调用。

白名单与黑名单:
白名单可以在Docket中对API和path进行相关配置,从而对某些服务放行。
黑名单可以通过注解@ApiIgnore来进行某些服务的忽略。

示例代码请猛戳这里下载参考。

原创粉丝点击