⼀、前⾔
在前后端分离开发的过程中,前端和后端需要进⾏api对接进⾏交互,就需要⼀个api规范⽂档,⽅便前后端的交互,但api⽂档不能根据代码的变化发⽣实时动态的改变,这样后端修改了接⼝,前端不能及时获取最新的接⼝,导致调⽤出错,需要⼿动维护api⽂档,加⼤了开发的⼯作量和困难,⽽swagger的出现就是为了解决这⼀系列的问题。
⼆、swagger的概述
swagger是⼀套基于OpenAPI规范构建的开源⼯具,使⽤RestApi1、代码变,⽂档变
2、跨语⾔,⽀持多种语⾔
3、swagger-ui 呈现出来的是⼀份可交互式的API⽂档,可以直接在⽂档页⾯尝试API的调⽤
4、可以将⽂档规范导⼊相关⼯具(postman、soapui),这些⼯具将会为我们⾃动地创建⾃动化测试补充:
RestApi格式是根据请求的⽅式决定本次请求的⼀个操作,譬如:get-->读,post-->写(增、删、改),put-->修改,delete-->删除
OpenApi与语⾔⽆关,只是⼀种规范,可以使⽤yaml和json格式进⾏编写,这样更利于我们和机器进⾏阅读swagger主要包含了以下三个部分:
swagger editor:基于浏览器的编辑器,我们可以使⽤它编写我们OpenApi规范(yaml或者json配置)
Swagger UI:他会将我们编写的OpenApi规范呈现为交互式的API⽂档,后⽂我将使⽤浏览器来查看并且操作我们的RestApiSwagger Codegen:它可以通过OpenApi规范定义的任何API⽣成服务器存根和客户端SDK来简化构建过程
使⽤swagger就是把相关信息存储在它定义的描述⽂件⾥⾯(yml或json格式),再通过维护这个描述⽂件可以去更新接⼝⽂档,以及⽣成各端代码
三、springfox概述
使⽤swagger时如果碰见版本更新迭代时,只需要更改swagger的描述⽂件即可,但是在频繁的更新项⽬版本时很多开发⼈员认为即使修改描述⽂件(yml或json⽂件)也是⼀定的⼯作负担,久⽽久之就直接修改代码,⽽不去修改描述⽂件了,这样基于描述⽂件⽣成接⼝⽂档也失去了意义。
Marty Pitt编写了⼀个基于spring的组件swagger-springmvc,Spring-fox就是根据这个组件发展⽽来的全新项⽬;
Spring-fox是根据代码⽣成接⼝⽂档,所以正常的进⾏更新项⽬版本,修改代码即可,⽽不需要跟随修改描述⽂件(yml或json⽂件);spring-fox利⽤⾃⾝AOP特性,把swagger集成进来,底层还是Swagger,但是使⽤起来却⽅便很多,所以在实际开发中,都是直接使⽤spring-fox。
四、swagger的使⽤
1、新建springboot项⽬2、导⼊相关依赖
3、启动类中添加@EnableSwagger2注解
@enableSwagger2:是springfox提供的⼀个注解,代表swagger2相关技术开启,会扫描当前类所在包,以及⼦包中所有的类型中的注解,做swagger⽂档的定值4、编写⼀个简单api接⼝
@RestController
public class HelloController {
@GetMapping(\"/get\") public String get() { return \"get\"; }
@PostMapping(\"/post\") public String post() { return \"post\"; }
@RequestMapping(\"/hello\") public String hello() { return \"hello\"; }}
4.1 swagger的基础信息配置-->config类
@Configuration
@EnableSwagger2 //开启swagger2,若启动类上添加了该注解,则配置类可以不添加public class SwaggerConfig {
// 创建swagger bean @Bean
public Docket docket() {
// Docket是swagger全局配置对象
// DocumentationType:指定⽂档类型为swagger2
return new Docket(DocumentationType.SWAGGER_2) // swagger信息 .apiInfo(apiInfo()); }
// swagger⽂档信息
public ApiInfo apiInfo() { // 作者信息
Contact contact = new Contact( // ⽂档发布者的名称 \"iqiuq\
// ⽂档发布者的⽹站地址
\"https://iqiuq.gitee.io/qiuqblogs/\ // ⽂档发布者的电⼦邮箱 \"qiuyonghui258@163.com\" );
return new ApiInfo( // 标题
\"iqiuq swagger api\ // ⽂档描述
\"演好⾃⼰⼈⽣的剧本\ // 版本号 \"1.0\
// 服务组url地址 \"urn:tos\ // 作者信息 contact, // 开源组织 \"Apache 2.0\ // 开源地址
\"http://www.apache.org/licenses/LICENSE-2.0\ // 集合
new ArrayList() ); }}
4.2 swagger扫描包配置
@Configuration
@EnableSwagger2 //开启swagger2public class SwaggerConfig {
// 创建swagger bean @Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2) // swagger信息 .apiInfo(apiInfo())
// swagger 扫描包配置
// select()获取Docket中的选择器,返回ApiSelectorBuilder构造选择器,如扫描扫描包的注解 .select() /**
* requestHandlerSelectors:请求处理选择器 * basePackage():扫描指定包下的所有接⼝ * any():扫描所有的包 * none():不扫描
* withClassAnnotation():扫描指定类上的注解,参数是⼀个注解的放射对象 * withMethodAnnotation():扫描⽅法上的注解
*/
// 指定扫描器扫描的规则(断⾔)
.apis(RequestHandlerSelectors.basePackage(\"com.iqiuq.swaggerdemo.controller\")) /**
* pathSelectors:路径选择器,过滤路径 * ang():选择所有路径 * none():都不选择 * ant():选择指定路径 * regex():正则表达式 */
.paths(PathSelectors.regex(\"/hello\")) .build(); }
return new ApiInfo( // 标题
\"iqiuq swagger api\ // ⽂档描述
\"演好⾃⼰⼈⽣的剧本\ // 版本号 \"1.0\
// 服务组url地址 \"urn:tos\ // 作者信息 contact, // 开源组织 \"Apache 2.0\ // 开源地址
\"http://www.apache.org/licenses/LICENSE-2.0\ // 集合
new ArrayList() );}
4.3 配置是否开启swagger
@Configuration
@EnableSwagger2 //开启swagger2public class SwaggerConfig {
// 创建swagger bean @Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2) // swagger信息 .apiInfo(apiInfo())
// 配置是否开启swagger,若为false,则浏览器不能访问 .enable(false); }
// swagger⽂档信息
public ApiInfo apiInfo() { // 作者信息
Contact contact = new Contact( \"iqiuq\
\"https://iqiuq.gitee.io/qiuqblogs/\ \"qiuyonghui258@163.com\"); return new ApiInfo(
\"iqiuq swagger api\ \"演好⾃⼰⼈⽣的剧本\ \"1.0\
\"urn:tos\ \"Apache 2.0\
\"http://www.apache.org/licenses/LICENSE-2.0\ new ArrayList()); }}
需求:开发和测试环境中开启swagger,其他环境不开启
@Configuration
@EnableSwagger2 //开启swagger2public class SwaggerConfig {
// 创建swagger bean @Bean
public Docket docket(Environment environment) { // 配置swagger的docket的bean实例
Profiles profiles = Profiles.of(\"dev\
// 通过environment.acceptsProfiles()判断是否指定的环境中,是,则为true boolean flag = environment.acceptsProfiles(profiles); return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo())
.enable(flag) .select()
.apis(RequestHandlerSelectors.basePackage(\"com.iqiuq.swaggerdemo.controller\")) .paths(PathSelectors.regex(\"/hello\")) .build(); }
// swagger⽂档信息
public ApiInfo apiInfo() {
Contact contact = new Contact( \"iqiuq\
\"https://iqiuq.gitee.io/qiuqblogs/\ \"qiuyonghui258@163.com\"); return new ApiInfo(
\"iqiuq swagger api\ \"演好⾃⼰⼈⽣的剧本\ \"1.0\ \"urn:tos\ contact,
\"Apache 2.0\
\"http://www.apache.org/licenses/LICENSE-2.0\ new ArrayList()); }}
4.3 swagger分组配置
每个组就是⼀个docket实例,多个组就是创建多个docket的实例
@Configuration
@EnableSwagger2 //开启swagger2public class SwaggerConfig {
// 创建swagger bean @Bean
public Docket docket1(Environment environment) { // 配置swagger的docket的bean实例
Profiles profiles = Profiles.of(\"dev\
// 通过environment.acceptsProfiles()判断是否指定的环境中,是,则为true boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2) // swagger信息 .apiInfo(apiInfo())
// 配置是否开启swagger,若为false,则浏览器不能访问 .enable(flag) // 配置组名
.groupName(\"iqiuq\") .select()
.apis(RequestHandlerSelectors.basePackage(\"com.iqiuq.swaggerdemo.controller\")) .paths(PathSelectors.regex(\"/hello\")) .build(); }
@Bean
public Docket docket2(Environment environment) { Profiles profiles = Profiles.of(\"dev\
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .enable(flag)
.groupName(\"哈哈哈\") .select()
.apis(RequestHandlerSelectors.basePackage(\"com.iqiuq.swaggerdemo.controller\")) .paths(PathSelectors.regex(\"/hello\")) .build(); }
@Bean
public Docket docket3(Environment environment) { Profiles profiles = Profiles.of(\"dev\
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .enable(flag)
.groupName(\"嘻嘻嘻\") .select()
.apis(RequestHandlerSelectors.basePackage(\"com.iqiuq.swaggerdemo.controller\")) .paths(PathSelectors.regex(\"/hello\")) .build();
}
// swagger⽂档信息
public ApiInfo apiInfo() {
Contact contact = new Contact( \"iqiuq\
\"https://iqiuq.gitee.io/qiuqblogs/\ \"qiuyonghui258@163.com\"); return new ApiInfo(
\"iqiuq swagger api\ \"演好⾃⼰⼈⽣的剧本\ \"1.0\ \"urn:tos\ contact,
\"Apache 2.0\
\"http://www.apache.org/licenses/LICENSE-2.0\ new ArrayList()); }
注意:
如果你使⽤的是swagger 3.0 你就需要使⽤
访问:http://localhost:8080/swagger-ui/index.html 就可以实现swagger-ui.html的访问
五、swagger常⽤注解
swagger注解主要是⽤来给swagger⽣成的接⼝⽂档说明⽤的5.1 @Api
@Api:是类上注解,控制整个类⽣成接⼝信息的内容
tags:类的名称,可以有多个值,多个值表⽰多个副本,在UI视图中就显⽰⼏个控制器访问菜单description:描述,已过时
5.2 @ApiOperation
@ApiOperation:⽅法的说明,value值必须提供
value:说明⽅法的作⽤notes:⽅法的备注说明
5.3 @ApiParam
@ApiParam:可以作⽤于⽅法参数和成员变量
name:参数别名value:参数的描述
required:是否必须需要
5.4 @ApiIgnore
@Apilgnore:忽略,当前注解描述的⽅法或类型,不⽣成api⽂档5.5 @ApiImplicitParam和@ApiImplicitParams
@ApiImplicitParam:使⽤在⽅法上,描述⽅法的单个参数
name:参数名称value:描述
required:是否必要参数paramType:参数类型dataType:数据类型
@ApiImplicitParams:使⽤在⽅法上,描述⽅法的⼀组参数
value:是@ApiImplicitParam类型的数组
5.6 @ApiModel和@ApiModelProperty
@ApiModel:描述⼀个实体类型,这个实体类型如果成为任何⼀个⽣成api帮助⽂档⽅法的⼀个返回值类型的时候,此注解被解析
value:⾃定义实体description:详细描述
@ApiModelProperty:实体类属性描述
name:字段别名value:字段描述
required:是否是必须字段example:⽰例数据hidden:是否隐藏数据5.7 @ApiResponse和@ApiResponses
@ApiResponses、@ApiResponse⽅法返回值的说明
@ApiResponses:⽅法返回对象的说明@ApiResponse:每个参数的说明
code:数字,例如:300
message:信息,例如:”请求参数没填好\"response:抛出异常的类5.8 其他注解
@Authorization:声明要在资源或操作上使⽤的授权⽅案@AuthorizationScope:描述OAuth2授权范围
@ResponseHeader:表⽰可以作为响应的⼀部分提供的标头@ApiProperty:描述POJO对象中的属性值@ApiError:接⼝错误所返回的信息
六、总结
1. 我们可以通过swagger给⼀些⽐较难理解的属性或接⼝,增加注释信息2. 接⼝⽂档实时更新3. 可以在线测试
4. 在正式发布的时候,关闭swagger,出于安全考虑,⽽且节省内存
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- cepb.cn 版权所有 湘ICP备2022005869号-7
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务