前言
说起Swagger就不得不说前后端分离
当前最主流的前后端分离技术栈:Vue+Springboot
后端时代:
前端只用管理静态页面:html
最后统一交给后端,后端将其修改为jsp,在整个过程中,后端充当主力
前后端分离时代:
后端:后端控制层,服务层,数据访问层【后端团队】
前端:前端控制层,视图层【前端团队】
前端可以自定义一些伪后端数据:json,在写的时候就存在,不需要后端,前端工程依旧能够跑起来
那么前端后端如何交互?
此时我们可以考虑API
前后端分离好处:
前后端相对独立,松耦合前后端设置可以部署在不同的服务器上
产生的问题:
前后弹集成联调,前端人员和后端人员无法做到及时协商,尽早解决,最终导致问题爆发;
解决方式:
首先指定schema[计划的提纲],实时更新最新的API,降低集成风险早期:指定word计划文档前后端分离时期:
前端测试后端接口:postman
后端提供接口,需要实时更新最新的消息及改动
在项目当中使用Swagger需要springbox;
swagger2ui
一、Swagger
号称世界上最流行的Api框架RestFul Api 文档在线自动生成工具,Api文档与Api定义同步更新直接运行,可以在线测试API接口支持多种语言:(Java,php等)官网地址:http://swagger.io/
二、SpringBoot集成Swagger
1.新建一个SpringBoot = web项目
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>
3.集成Swagger ==>Config
@EnableSwagger2 用来开启Swagger2
@Configuration@EnableSwagger2 //开启Swagger2public class SwaggerConfig {}
4.进入测试
http://localhost:8080/swagger-ui.html
配置Swagger
# 配置Swagger基本信息Swagger的Bean实例Docket:
package com.fwp.swagger.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;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;import java.util.ArrayList;@Configuration@EnableSwagger2 //开启Swagger2public class SwaggerConfig {//配置了Swagger的Docket的Bean实例@Beanpublic Docket docket(){return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()//RequestHandlerSelectors配置要扫描接口的方式//basePackage指定要扫描的包//any() 扫描全部//none() 都不扫描//withClassAnnotation() 扫描类上的注解,参数是一个注解的反射对象//withMethodAnnotation() 扫描上的注解,参数是一个注解的反射对象.apis(RequestHandlerSelectors.basePackage("com/fwp/swagger/controller")).paths(PathSelectors.ant("/fwp/**")).build();}//配置Swagger信息=apiInfoprivate ApiInfo apiInfo(){//作者信息Contact contact = new Contact("鹏鹏", "/weixin_51132678?type=blog", "3230609771@");return new ApiInfo("鹏鹏的SwaggerAPI文档","即使再小的船也能上岸","1.0","/weixin_51132678?type=blog",contact,"Apache 2.0","/licenses/LICENSE-2.0",new ArrayList());}}
三、Swagger配置扫描接口
Docket.select()
//配置了Swagger的Docket的Bean实例@Beanpublic Docket docket(){return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()//RequestHandlerSelectors配置要扫描接口的方式//basePackage指定要扫描的包//any() 扫描全部//none() 都不扫描//withClassAnnotation() 扫描类上的注解,参数是一个注解的反射对象//withMethodAnnotation() 扫描方法上的注解,参数是一个注解的反射对象.apis(RequestHandlerSelectors.basePackage("com.fwp.swagger.controller"))//过滤.paths(PathSelectors.ant("/fwp/**")).build();}
配置是否启动swagger
enable是否启动swagger。如果为false,则swagger在浏览器中不能访问
//配置了Swagger的Docket的Bean实例@Beanpublic Docket docket(){return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(false)
swagger启动失败
那么如果我们希望Swagger在某一个环境中使用,在其他时候不使用怎么办
dev环境下:
server.port=8081
pro环境下:
server.port=8082
application.properties文件
spring.profiles.active=dev
此时我们处于dev环境下,我们希望swagger在dev环境下能使用,在其他环境下不能使用
@Configuration@EnableSwagger2 //开启Swagger2public class SwaggerConfig {//配置了Swagger的Docket的Bean实例@Beanpublic Docket docket(Environment environment){//设置要显示的Swagger环境 可返回多个Profiles profiles = Profiles.of("dev","test");//获取生产环境//通过environment.acceptsProfiles(profiles)判断自己是否处在指定环境boolean flag = environment.acceptsProfiles(profiles);System.out.println(flag);return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(flag)//enable是否启动swagger。如果为false,则swagger在浏览器中不能访问.select().apis(RequestHandlerSelectors.basePackage("com.fwp.swagger.controller"))//过滤//.paths(PathSelectors.ant("/fwp/**")).build();}//配置Swagger信息=apiInfoprivate ApiInfo apiInfo(){//作者信息Contact contact = new Contact("鹏鹏", "/weixin_51132678?type=blog", "3230609771@");return new ApiInfo("鹏鹏的SwaggerAPI文档","即使再小的船也能上岸","1.0","/weixin_51132678?type=blog",contact,"Apache 2.0","/licenses/LICENSE-2.0",new ArrayList());}}
将enable()中的参数值设置为flag,这样当我们处于dev与test环境下时swagger默认开启,其他情况下默认关闭
进入dev环境
进入pro环境
四、配置API文档分组
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).groupName("鹏鹏")
如果我们想配置多个分组怎么办呢?
创建多个docket对象,设置不同的组名
@Beanpublic Docket docket1(){return new Docket(DocumentationType.SWAGGER_2).groupName("A");}@Beanpublic Docket docket2(){return new Docket(DocumentationType.SWAGGER_2).groupName("B");}@Beanpublic Docket docket3(){return new Docket(DocumentationType.SWAGGER_2).groupName("C");}
可以看见页面中出现了不同的组别,每个组别之间互不干扰,利于合作开发,每个人扫描自己的包,做自己的事情
五、实体类的配置
User类
@Data@AllArgsConstructor@NoArgsConstructor//@Api("注释")@ApiModel("用户实体类")public class User {@ApiModelProperty("用户名")public String username;@ApiModelProperty("密码")public String password;}
HelloController中:
//只要返回值中存在实体类,他就会被扫描到Swagger中@PostMapping("/user")public User user(){return new User("pp","123");}
文档注解
为了方便交互,方便文档阅读,我们可以为文档添加说明信息
@ApiModel(“用户实体类”)为实体类添加说明信息
@ApiModelProperty(“用户名”)为实体类中的属性添加说明信息
@Api(tags = “控制器-hello”)为接口添加说明信息
@ApiOperation(“hello请求”)为请求增加说明信息
@ApiParam(“hello请求中的name”)为请求中的参数增加说明信息
实体类
@Data@AllArgsConstructor@NoArgsConstructor//@Api("注释")@ApiModel("用户实体类")public class User {@ApiModelProperty("用户名")public String username;@ApiModelProperty("密码")public String password;}
HelloController:
@RestControllerpublic class HelloController {@GetMapping("/hello")public String hello(){return "hello!!!";}//只要返回值中存在实体类,他就会被扫描到Swagger中@PostMapping("/user")public User user(){return new User("pp","123");}//Operation接口 放在方法上而不是类上@ApiOperation("Hello控制类")@GetMapping("/hello2")public String hello2(@ApiParam("用户名") String username){return "hello!!!"+username;}
添加注释后展示:
总结
我们可以通过Swagger给一些比较难理解的属性或者接口,增加注释信息接口文档实时更新可以在线测试注意点:
在正式发布的时候,需要关闭Swagger,一是出于安全考虑,,二是节省内存