1、Swagger的概念及使用
接口现状以及Swagger介绍
(1)接口现状
前后端分离
- 前端 -> 前端控制层、视图层
- 后端 -> 后端控制层、服务层、数据访问层
前后端通过API进行交互
前后端相对独立且松耦合
产生问题
- 前后端集成,前端或者后端无法做到“及时协商,尽早解决”,最终导致问题集中爆发
解决方案 - 首先定义schema [ 计划的提纲 ],并实时跟踪最新的API,降低集成风险
(2)swagger介绍
Swagger号称世界上最流行的API框架,Restful Api 文档在线自动生成器 => API 文档 与API 定义同步更新,直接运行,在线测试API,支持多种语言 (如:Java,PHP等)
官网:https://swagger.io/
2、SpringBoot集成Swagger
若要使用swagger则需要jdk8的环境
步骤:
导入依赖springfox-swagger2和springfox-swagger-ui
<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>
编写Controller
创建配置类并在配置类上使用注解开启swagger
@Configuration //标注类为配置类
@EnableSwagger2 //开启swagger
public class SwaggerConfig {
}
测试 访问:http://localhost/swagger-ui.html
配置Swagger
步骤:
在配置类中,将Docket配置注入的bean中
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2);
}
查看Docket源码
public class Docket implements DocumentationPlugin {
public static final String DEFAULT_GROUP_NAME = "default";
private final DocumentationType documentationType;
private final List<SecurityContext> securityContexts = Lists.newArrayList();
private final Map<RequestMethod, List<ResponseMessage>> responseMessages = Maps.newHashMap();
private final List<Parameter> globalOperationParameters = Lists.newArrayList();
private final List<Function<TypeResolver, AlternateTypeRule>> ruleBuilders = Lists.newArrayList();
private final Set<Class> ignorableParameterTypes = Sets.newHashSet();
private final Set<String> protocols = Sets.newHashSet();
private final Set<String> produces = Sets.newHashSet();
private final Set<String> consumes = Sets.newHashSet();
private final Set<ResolvedType> additionalModels = Sets.newHashSet();
private final Set<Tag> tags = Sets.newHashSet();
private PathProvider pathProvider;
private List<? extends SecurityScheme> securitySchemes;
private Ordering<ApiListingReference> apiListingReferenceOrdering;
private Ordering<ApiDescription> apiDescriptionOrdering;
private Ordering<Operation> operationOrdering;
private ApiInfo apiInfo;
private String groupName;
private boolean enabled;
private GenericTypeNamingStrategy genericsNamingStrategy;
private boolean applyDefaultResponseMessages;
private String host;
private Optional<String> pathMapping;
private ApiSelector apiSelector;
private boolean enableUrlTemplating;
private List<VendorExtension> vendorExtensions;
//配置参数
public Docket(DocumentationType documentationType) {
this.apiInfo = ApiInfo.DEFAULT; //不配置默认使用
this.groupName = "default";
this.enabled = true;
this.genericsNamingStrategy = new DefaultGenericTypeNamingStrategy();
this.applyDefaultResponseMessages = true;
this.host = "";
this.pathMapping = Optional.absent();
this.apiSelector = ApiSelector.DEFAULT;
this.enableUrlTemplating = false;
this.vendorExtensions = Lists.newArrayList();
this.documentationType = documentationType;
}
编写一个ApiConfig的私有方法配置swagger
//配置swagger信息=apiInfo
private ApiInfo apiInfo() {
Contact contact = new Contact("JackStyle", "http://121.5.162.75/mjblog-0.0.1-SNAPSHOT/", "1324521801@qq.com");
return new ApiInfo(
"Swagger学习", // 标题
"学习演示如何配置Swagger", // 描述
"v1.0", // 版本
"https://www.360.cn", // 组织链接
contact, // 联系人信息
"Apach 2.0 许可", // 许可
"http://www.baidu.com", // 许可连接
new ArrayList<>()// 扩展
);
}
bean调用私有方法调用
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}
测试
访问:http://localhost/swagger-ui.html
配置扫描
即指定或扫描的接口
方式一:
配置apis
在bean中.select().apis(…).build()
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(RequestMapping.class))
.build();
}
其中可以RequestHandlerSelectors类对应的方法有多个,可以通过配置其方法,来控制筛选的方式
- basePackage:指定扫描的包
- any:扫描全部
- none:都不扫描
- withClassAnnotation:扫描类身上的接口
- withMethodAnnotation:扫描对应注解的接口
方式二:
通过配置paths
在bean中.select().paths(…).build()
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(RequestMapping.class))
.paths(PathSelectors.ant("/jackstyle/**"))
.build();
}
其中PathSelectors类对应的方法也有多个,可以通过配置其方法,来控制筛选的方式
PathSelectors
- ant() 根据路径扫描
- none:都不扫描
- any:都扫描
- reges:通过正则表达式控制
注意:.apis与paths可以一起使用,加强了筛选力度
Swagger启动与关闭
通过在bean中配置enable() true:开启 false:关闭
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(false) //swagger启动开关
}
在真实项目中不会让手动去改代码,所以我们可以通过检测使用的配置文件来区分当前的是什么版本,正常开发会将配置文件分为appliction、application-dev、application-pro
配置步骤:
- 在bean设置接收参数Environment environment
(注意导入的是org.springframework.core.env.Environment) - 创建Profiles对象设置参数为dev与test
- environment.acceptsProfiles(profiles);获取返回值,判断是预先设置的环境 将返回值设置到enable中
@Bean
public Docket docket(Environment environment) {
//设置要显示的swagger环境
Profiles profiles = Profiles.of("dev","test");
//判断当前开发环境
//获取项目的环境
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(flag) //swagger启动开关
}
测试
application.yml
spring:
profiles:
active: pro
application-dev.yml
server:
port: 8088
application-pro.yml
server:
port: 8089
当 启动项目访问:http://localhsot:8089/swagger-ui.html时就不阻拦不给访问
配置Api文档的分组
在bean加上以下配置
.groupName("JackStyle") //字符串为设置组名
如何配置多个分组:
可以配置多个Docket,但注意名字不要相同
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2).groupName("A");
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("B");
}
@Bean
public Docket docket3(){
return new Docket(DocumentationType.SWAGGER_2).groupName("C");
}
实体类配置
swagger提供了一些注解用来标注内容,添加备注
- @Api(“xxxxx”) //标注在类上用来备注模块类
- @ApiModel(“xxxxx”) //用于标注在实体类头部添加备注
- @ApiModelProperty(“xxxxx”) //用于标注在实体类属性上添加备注
- @ApiOperation(“xxxx”) //用于添加在接口 上备注接口
- @ApiParam(“xxxx”) //用于标注到参数上添加备注
eg:
@Api
@Api(tags = {"hello控制层"})
@RestController
public class HelloworldController {
}
@ApiModel&@ApiModelProperty
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("用户实体类")
public class user {
@ApiModelProperty("用户名")
private String username;
@ApiModelProperty("用户密码")
private String password;
}
@ApiOperation&@ApiParam
@RestController
public class HelloworldController {
@ApiOperation("问好")
@RequestMapping("/hello")
public String hello(){
return "hello swagger";
}
@PostMapping("/user")
public user getUser(@ApiParam("用户id") String id,@ApiParam("用户名")String username){
return new user();
}
使用Swagger在线测试
eg:
//为接口加注释
@Api(tags = {"hello控制层"})
@RestController
public class HelloworldController {
@PostMapping("/user")
public user getUser( @ApiParam("用户id")@RequestParam("id") Integer id,@ApiParam("用户名")@RequestParam("username") String username, @ApiParam("用户密码")@RequestParam("password") String password){
System.out.println(id+"------------"+username+"------"+password);
return new user(id,username,password);
}
@PostMapping("/user2")
public user getUser2(@ApiParam("用户") user user){
System.out.println(user);
return user;
}
}
测试/user
测试/user2
同理以上,但这补充一个知识点,当swagger以json发送post时,后端接收单个数据时,使用 @RequestParam(“参数名”)
扩展知识
Swagger导入不同的包其皮肤可以不同
当前皮肤使用springfoxs-swagger-ui
访问:http://localhost/swagger-ui.html
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2.使用bootstrap-ui的界面
访问:http://localhost/doc.html
3.使用mg-ui的界面
访问:http://localhost/document.html