Swagger
1.学习目标:
-
了解Sagger的作用和概念
-
了解前后端分离
-
在springboot中集成Swagger
1.Swagger简介
前后端分离:Vue+Springboot
后端时代:
前端只用管理静态页面,将整个html交给后端;后端的模板引擎JSP, 后端 是主力。
前后端分离时代:
-
后端:后端控制层,服务层,数据访问层
-
前端:前端控制层,视图层
-
前端可以伪造后端的数据,通过json跟后端进行交互。现在已经不需要后端,前端工程依然可以运行起来。
-
-
前后端交互方式:API接口
-
前后端相对独立,松耦合
-
前后端甚至可以部署到不同的服务器上面
产生的问题:
-
前后端集成联调,前端人员和后端人员无法做到及时协商以便尽快解决问题,最终将导致问题集中爆发;简单来讲,也就是前端不知道后端将提供给前端的接口名字以及后端将传送给前端的数据以及数据类型。。
解决方案:
-
首先应该指定计划,实时更新后端提供给前端的最新API,来降低集成的风险。
-
比如早些年,会指定word计划文档
-
前后端分离:
-
前端测试后端的接口:postman
-
后端提供接口,需要实时更新最新的消息以及改动
-
不太方便:这样需要特定去下载安装postman
-
2.Swagger:
-
是世界上最流行的API框架
-
RestFull Api文档在线自动生成工具==》Api文档与API接口定义同步更新
-
直接运行,可以在线测试API接口
-
支持多种语言:java , Php
4.在项目中使用swagger需要导入架包springbox
-
swagger2
-
ui
3.Springboot集成swagger
1.在IDEA里面新建一个sprongboot----web项目
1.打开IDEA,File-->New--->Project
若在此步出现如下错误:
解决方法为:先点击ok
方法1.然后点击下面指定位置进行刷新
方法2:若多次刷新没有效果,则放弃该次项目的创建,重建项目,本人亲测有效。
3.点击next
4.点击next后,选择一个纯springboot项目:如下:
2.导入相关依赖:
在pom.xml文件中导入依赖:
<!--https://mvnrepository.com/artifact/io.springfox/springfox-swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
如果和我一样报如下错误:点击刷新即可,如下:
如果打开的目录是这样的,包名在一起了,没有成一级一级的分开:
解决办法如下,找到compact Middle Packages并去掉打勾可解决办法:
3.编写一个hello工程
1.在src-->main-->java---新建一个名为controller的包
2.在新建的包下面右键创建一个HelloController类,然后回车即可:
3.到文件HelloController类中,写入如下代码:
package com.example.swagger.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello";
}
}
4.到启动文件中(含有方法名为public static void main(String[] args)的文件中),按如下所示运行起来:
5.若在左下角的控制台下面如下图所示则运行成功:
6.打开浏览器输入网址:localhost:8080/hello,若出来下面的图,则运行正确:
4.配置swagger:
1.在pom.xml文件中加入以下依赖并及时从maven仓库中下载资源:
在pom.xml文件中导入依赖:
<!--https://mvnrepository.com/artifact/io.springfox/springfox-swagger2-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!--https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2.创建与Controller同一级的包名为Config,并在改包下面创建类SwaggerConfig,最终文件展示如下:
3.在SwaggerConfig中加入如下内容:
package com.example.swagger.config;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2 //开启swagger2
public class SwaggerConfig {
}
4.运行,在启动文件中进行运行,一开始运行的时候报的错误为空指针异常,我也在网上试了很多方法,比如查看是不是端口号被占用,或者在pom.xml文件中更换springboot版本,或者在pom.xml文件中更换swagger版本,但是最终都没能够解决。随后,我直接将项目删除了,从头新建一个一摸一样的项目,并且按步骤先将springboot版本从2.6.4改为2.2.7并且将swagger的依赖加入到pom.xml文件中,最后进行一次性的maven加载资源包,才能够获取成功。
运行成功如下:
5.通过网址Swagger UI进行测试:出现如下图则成功:
4.配置swagger
Swagger有自己的一个bean实例Docket;
1.在文件SwaggerConfig中配置相关swagger的基本信息:
package com.example.swaggerdemo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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;
import static springfox.documentation.service.ApiInfo.DEFAULT_CONTACT;
@Configuration
@EnableSwagger2 //开启swagger2
public class SwaggerConfig {
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(){//该方法返回对象为Docket,并将该对象注入到Bean里面
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}
//配置swagger的信息等于apiInfo
private ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("刘艳","https://blog.kuangstudy.com/","2890850899@qq.com");
return new ApiInfo(
"刘艳",//标题
"nihaoya",//描述
"v1.0",//版本
"https://blog.kuangstudy.com/",//组织名或者作者信息或者博客网址
DEFAULT_CONTACT,
"Apache 2.0",
"http:www.apache.org/licenses/LICENSE-2.0",
new ArrayList()
);
};
}
2.重新运行该项目,运行成功后,进入网址Swagger UI测试如下图:
3.可以点开hello-controller知道如下,:
明明在此之前我们只有一个接口,但是会有那么多get ,post 等等路径,这是因为在我们的hellocontroller文件中只有一个@RequestMapping,,,并没有指明到底是getmapping还是postmapping或者其它方式。
5.Swagger配置扫描接口
1.配置扫描接口Docket.select()
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(){//该方法返回对象为Docket,并将该对象注入到Bean里面
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//RequestHandlerSelectors配置要扫描接口的方式.
// basePackage()表示指定要扫描的包,参数为包的路径,一般会使用的方法
//any()表示扫描所有的包
//none()表示所有包都不扫描
//withClassAnnotation表示扫描类上面的注解,参数为一个注解的反射对象,值可以为:@GetMapping.class
//withMethodAnnotation表示扫描方法上面的注解
.apis(RequestHandlerSelectors.basePackage("com.example.swaggerdemo.controller"))
//path表示过滤,常用的为ant()
//.paths(PathSelectors.ant("/example/**"))
.build();
}
上面代码中.apis(RequestHandlerSelectors.basePackage("com.example.swaggerdemo.controller"))表示只扫描包com.example.swaggerdemo.controller,所以当我们打开网址Swagger UI可以看到只有一个接口信息:
2.配置是否启动swagger
//enable为是否启动swagger,如果为false,则swagger不能在浏览器中访问
@Bean
public Docket docket(){//该方法返回对象为Docket,并将该对象注入到Bean里面
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(false)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.swaggerdemo.controller"))
.build();
}
配置完成后,重新运行项目,然后重新浏览swagger的网址,会出现下图所示:
问题:我只希望我的swagger在生产环境中使用,在发布的时候不使用?
-
判断是不是生产环境 flag=false
-
注入enable(flag)
进行多配置的方法:
1.第一套环境:在resources下面新建生产环境文件application-dev.properties 并输入以下内容:
server.port=8081
2.第二套环境,在resources下面新建生产环境文件application-pro.properties 并输入以下内容:
server.port=8082
3.在文件SwaggerConfig中按如下设置:
//配置了swagger的Docket的bean实例
@Bean
public Docket docket(Environment environment){//该方法返回对象为Docket,并将该对象注入到Bean里面
//设置要显示的swagger环境
Profiles profiles = Profiles.of("dev","test");
//获取项目的环境:
//通过environment.acceptsProfiles判断是否处在自己设定的环境中
//如果系统检测到当前环境为dev或者test则flag为true,否则为flase
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(flag)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.swaggerdemo.controller"))
.build();
}
4.重新运行swagger网址http://localhost:8080/swagger-ui.html,发现如下面所示:这是因为我们没有检测到当前环境,所以flag为flase
因此我们需要指定当前环境,步骤如下:
1.在resources下面的文件application.properties中输入以下代码,用来确定激活当前用哪一套环境:
spring.profiles.active=dev
//指定当前环境为dev
2.然后再重新运行网址http://localhost:8081/swagger-ui.html,该网址的8080变为8081,是因为我们已经指定了当前环境为dev环境且该环境的端口号为8081。发现如下面所示:这是因为系统检测到当前环境为dev,所以flag为true:
注意:如果我们的swagger网址端口号为8080,将会出现如下错误:
6.配置API文档的分组
1.只有一个分组:在文件swaggerconfig.java中一定位置加入以下代码
.groupName("zhangsan")//组名
运行项目后打开swagger网址为下图所示:
2.存在多个分组时,一个Docket对象代表一个祖,创建多个对象就会有多个组:文件swaggerconfig.java中代码如下:
//多个组
@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网址为下图所示:
7.实体类配置
1.创建一个与controller包同等级的文件夹pojo,并在该文件下创建一个类User:
2.在实体类User中添加属性如下:
package com.example.swaggerdemo.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("用户实体类")//给实体类的文档注释
public class User {
@ApiModelProperty("用户名")//给属性的文档注释
public String username;
@ApiModelProperty("密码")
public String password;
}
3.修改HelloController里面的内容如下:
package com.example.swaggerdemo.controller;
import com.example.swaggerdemo.pojo.User;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
// @RequestMapping("/hello")
// public String hello(){
// return "hello";
// }
@GetMapping("/hello")
public String hello(){
return "hello";
}
//只要我们的接口中,返回值存在实体类,它就会被扫描到Swagger中
@PostMapping("/user")
public User user(){
return new User();
}
//Operation接口,不是放在类上,而是放在接口上
@ApiOperation("hello控制类")
@GetMapping("/hello2")
public String hello2(@ApiParam("这是用户名") String username){//@ApiParam("用户名")为参数的注释
return "hello"+username;
}
}
4.运行项目后打开swagger网址为下图所示:
总结:
-
我们可以通过Swagger给一些比较难以理解的属性或者接口,增加注释信息
-
接口文档实时更新
-
可以在线测试
-
是一个非常优秀的工具,几乎所有大公司都使用
-
注意点:在正式发布的时候,关闭swagger.出于安全考虑,节省内存。