Swagger 简介
https://www.ibm.com/developerworks/cn/java/j-using-swagger-in-a-spring-boot-project/index.html
Swagger 是一套基于 OpenAPI 规范构建的开源工具,可以帮助我们设计、构建、记录以及使用 Rest API。Swagger 主要包含了以下三个部分:
- Swagger Editor:基于浏览器的编辑器,我们可以使用它编写我们 OpenAPI 规范。
- Swagger UI:它会将我们编写的 OpenAPI 规范呈现为交互式的 API 文档,后文我将使用浏览器来查看并且操作我们的 Rest API。
- Swagger Codegen:它可以通过为 OpenAPI(以前称为 Swagger)规范定义的任何 API 生成服务器存根和客户端 SDK 来简化构建过程。
很大一部分Spring Boot的用户会用来构建RESTful API。而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端。
这样一来,我们的RESTful API就有可能要面对多个开发人员或多个开发团队:IOS开发、Android开发或是Web开发等。为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTful API文档来记录所有接口细节,然而这样的做法有以下几个问题:
- 由于接口众多,并且细节复杂(需要考虑不同的HTTP请求类型、HTTP头部信息、HTTP请求内容等),高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。
- 随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。
swagger用于定义API文档。
好处:
- 前后端分离开发
- API文档非常明确
- 测试的时候不需要再使用URL输入浏览器的方式来访问Controller
- 传统的输入URL的测试方式对于post请求的传参比较麻烦(当然,可以使用postman这样的浏览器插件)
- spring-boot与swagger的集成简单
导入依赖
<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>
Application.java
1 package com.xxx.firstboot; 2 3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5 6 import springfox.documentation.swagger2.annotations.EnableSwagger2; 7 8 @SpringBootApplication //same as @Configuration+@EnableAutoConfiguration+@ComponentScan 9 @EnableSwagger2 //启动swagger注解 10 public class Application { 11 12 public static void main(String[] args) { 13 SpringApplication.run(Application.class, args); 14 } 15 16 }
- 引入了一个注解@EnableSwagger2来启动swagger注解。(启动该注解使得用在controller中的swagger注解生效,覆盖的范围由@ComponentScan的配置来指定,这里默认指定为根路径"com.xxx.firstboot"下的所有controller)
UserController.java
1 package com.xxx.firstboot.web; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.web.bind.annotation.RequestHeader; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.RequestMethod; 7 import org.springframework.web.bind.annotation.RequestParam; 8 import org.springframework.web.bind.annotation.RestController; 9 10 import com.xxx.firstboot.domain.User; 11 import com.xxx.firstboot.service.UserService; 12 13 import io.swagger.annotations.Api; 14 import io.swagger.annotations.ApiImplicitParam; 15 import io.swagger.annotations.ApiImplicitParams; 16 import io.swagger.annotations.ApiOperation; 17 import io.swagger.annotations.ApiResponse; 18 import io.swagger.annotations.ApiResponses; 19 20 @RestController 21 @RequestMapping("/user") 22 @Api("userController相关api") 23 public class UserController { 24 25 @Autowired 26 private UserService userService; 27 28 // @Autowired 29 // private MyRedisTemplate myRedisTemplate; 30 31 @ApiOperation("获取用户信息") 32 @ApiImplicitParams({ 33 @ApiImplicitParam(paramType="header",name="username",dataType="String",required=true,value="用户的姓名",defaultValue="zhaojigang"), 34 @ApiImplicitParam(paramType="query",name="password",dataType="String",required=true,value="用户的密码",defaultValue="wangna") 35 }) 36 @ApiResponses({ 37 @ApiResponse(code=400,message="请求参数没填好"), 38 @ApiResponse(code=404,message="请求路径没有或页面跳转路径不对") 39 }) 40 @RequestMapping(value="/getUser",method=RequestMethod.GET) 41 public User getUser(@RequestHeader("username") String username, @RequestParam("password") String password) { 42 return userService.getUser(username,password); 43 } 44 45 // @RequestMapping("/testJedisCluster") 46 // public User testJedisCluster(@RequestParam("username") String username){ 47 // String value = myRedisTemplate.get(MyConstants.USER_FORWARD_CACHE_PREFIX, username); 48 // if(StringUtils.isBlank(value)){ 49 // myRedisTemplate.set(MyConstants.USER_FORWARD_CACHE_PREFIX, username, JSON.toJSONString(getUser())); 50 // return null; 51 // } 52 // return JSON.parseObject(value, User.class); 53 // } 54 55 }
说明:
- @Api:用在类上,说明该类的作用
- @ApiOperation:用在方法上,说明方法的作用
- @ApiImplicitParams:用在方法上包含一组参数说明
- @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
- paramType:参数放在哪个地方
- header-->请求参数的获取:@RequestHeader
- query-->请求参数的获取:@RequestParam
- path(用于restful接口)-->请求参数的获取:@PathVariable
- body(不常用)
- form(不常用)
- name:参数名
- dataType:参数类型
- required:参数是否必须传
- value:参数的意思
- defaultValue:参数的默认值
- paramType:参数放在哪个地方
- @ApiResponses:用于表示一组响应
- @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
- code:数字,例如400
- message:信息,例如"请求参数没填好"
- response:抛出异常的类
- @ApiModel:描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)
- @ApiModelProperty:描述一个model的属性
以上这些就是最常用的几个注解了。
有了上面的基础
查看终端支付时运用的代码
package springboot; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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: DengLibin * @ Description: http://localhost/swagger-ui.html * @ DateTime: 14:05 2018/5/15 0015 */ @Configuration @EnableSwagger2 //启用Swagger2 public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .enable(true) .select() .apis(RequestHandlerSelectors.basePackage("com.allinpay.pay.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Spring Boot中使用Swagger2构建Restful API") .description("基于springBoot的整合开发") .termsOfServiceUrl("https://swagger.io/") .contact( new Contact("--","--","--")) .version("1.0") .build(); } }
Springfox 提供了一个 Docket 对象,让我们可以灵活的配置 Swagger 的各项属性
如上代码所示,通过@Configuration
注解,让Spring来加载该类配置。再通过@EnableSwagger2
注解来启用Swagger2。
再通过createRestApi
函数创建Docket
的Bean之后,apiInfo()
用来创建该Api的基本信息(这些基本信息会展现在文档页面中)。select()
函数返回一个ApiSelectorBuilder
实例用来控制哪些接口暴露给Swagger来展现,本例采用指定扫描的包路径来定义,Swagger会扫描该包下所有Controller定义的API,并产生文档内容(除了被@ApiIgnore
指定的请求)。
访问验证
其实就只需要添加一下依赖就可以了,我们重新启动一下项目,然后在浏览器中访问 http://localhost:8080/swagger-ui.html
接口过滤
有些时候我们并不是希望所有的 Rest API 都呈现在文档上,这种情况下 Swagger2 提供给我们了两种方式配置,一种是基于 @ApiIgnore
注解,另一种是在 Docket 上增加筛选。
@ApiIgnore
注解。如果想在文档中屏蔽掉删除用户的接口(user/delete),那么只需要在删除用户的方法上加上 @ApiIgnore 即可。
@ApiIgnore public boolean delete(@PathVariable("id") int id)