前后端分离简介:
前端 -> 前端控制层、视图层
后端 -> 后端控制层、服务层、数据访问层
前后端通过API进行交互
前后端相对独立且松耦合
Swagger简介:
Restful Api 文档在线自动生成器 => API 文档 与API 定义同步更新
直接运行,在线测试API
只需要录入数据然后点击Execute,如果再配合自动化框架,可以说基本就不需要人为操作了。
提醒下大家在正式环境要记得关闭Swagger,一来出于安全考虑二来也可以节省运行时内存。
使用Swagger:
<!-- swagger核心jar包-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- swagger界面jar包-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
@Configuration //配置类
@EnableSwagger2// 开启Swagger2的自动配置
public class SwaggerConfig {
}
配置Swagger:
Swagger实例Bean是Docket
,所以通过配置Docket实例来配置Swaggger。@Bean //配置docket以配置Swagger具体参数
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2);
}
可以通过apiInfo()属性配置文档信息
//配置文档信息
private ApiInfo apiInfo() {
Contact contact = new Contact("联系人名字", "http://xxx.xxx.com/联系人访问链接", "联系人邮箱");
return new ApiInfo(
"Swagger学习", // 标题
"学习演示如何配置Swagger", // 描述
"v1.0", // 版本
"http://terms.service.url/组织链接", // 组织链接
contact, // 联系人信息
"Apach 2.0 许可", // 许可
"许可链接", // 许可连接
new ArrayList<>()// 扩展
);
}
Docket 实例关联上apiInfo()
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo());
}
配置扫描接口:
构建Docket时通过select()方法配置怎么扫描接口。
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
.apis(RequestHandlerSelectors.basePackage("com.george.swagger.controller"))
.build();
}
--------------RequestHandlerSelectors的可选值还有:--------------
any() // 扫描所有,项目中的所有接口都会被扫描到
none() // 不扫描接口
// 通过方法上的注解扫描,如withMethodAnnotation(GetMapping.class)只扫描get请求
withMethodAnnotation(final Class<? extends Annotation> annotation)
// 通过类上的注解扫描,如.withClassAnnotation(Controller.class)只扫描有controller注解的类中的接
withClassAnnotation(final Class<? extends Annotation> annotation)
basePackage(final String basePackage) // 根据包路径扫描接口
除此之外我们还可以配置接口扫描过滤:
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
.apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
// 配置如何通过path过滤,即这里只扫描请求以/lin开头的接口
.paths(PathSelectors.ant("/lin/**"))
.build();
}
-------PathSelectors的可选值还有:-------
any() // 任何请求都扫描
none() // 任何请求都不扫描
regex(final String pathRegex) // 通过正则表达式控制
ant(final String antPattern) // 通过ant()控制
配置Swagger开关:
通过enable()方法配置是否启用swagger
,如果是false,swagger将不能在浏览器中访问了@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(false) //配置是否启用Swagger,如果是false,在浏览器将无法访问
.select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
.apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
// 配置如何通过path过滤,即这里只扫描请求以/kuang开头的接口
.paths(PathSelectors.ant("/kuang/**"))
.build();
}
动态配置当项目处于test、dev环境时显示swagger,处于prod时不显示。
@Bean
public Docket docket(Environment environment) {
// 设置要显示swagger的环境
Profiles of = Profiles.of("dev", "test");
// 判断当前是否处于该环境
// 通过 enable() 接收此参数判断是否要显示
boolean b = environment.acceptsProfiles(of);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(b) //配置是否启用Swagger,如果是false,在浏览器将无法访问
.select()// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口
.apis(RequestHandlerSelectors.basePackage("com.kuang.swagger.controller"))
// 配置如何通过path过滤,即这里只扫描请求以/kuang开头的接口
.paths(PathSelectors.ant("/kuang/**"))
.build();
}
配置API分组:
如果没有配置分组,默认是default,可以通过groupName()方法配置分组
:@Bean
public Docket docket(Environment environment) {
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo())
.groupName("hello") // 配置分组
// 省略配置....
}
配置多个分组只需要配置多个docket即可。
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2).groupName("group1");
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("group2");
}
@Bean
public Docket docket3(){
return new Docket(DocumentationType.SWAGGER_2).groupName("group3");
}
实体配置:
@ApiModel("用户实体")
public class User {
@ApiModelProperty("用户名")
public String username;
@ApiModelProperty("密码")
public String password;
}
只要这个实体在请求接口的返回值上(即使是泛型)都能映射到实体项中。
@RequestMapping("/getUser")
public User getUser(){
return new User();
}
并不是因为@ApiModel这个注解让实体显示在这里了,而是只要出现在接口方法的返回值上的实体都会显示在这里,而@ApiModel和@ApiModelProperty这两个注解只是为实体添加注释的。
常用注解简介:
Swagger注解 | 简单说明 |
---|---|
@Api | 用在请求的类上表示对类(controller类) 的说明。tags= “说明该类的作用,可以在UI界面上看到的注解”,value= “该参数没什么意义,在UI界面上也看到,所以不需要配置” |
@ApiOperation | 用在请求的方法(controller类的方法) 上说明方法的用途和作用。value= “说明方法的用途、作用”,notes= “方法的备注说明” |
@ApiModel | 用于响应类(javaBean类) 上表示一个返回响应数据的信息 |
@ApiModelProperty | 用在属性上,描述响应类的属性(javaBean类的方法或属性) |
@ApiImplicitParams | 用在请求的方法(controller类的方法) 上,表示一组参数说明 |
@ApiImplicitParam | 用在@ApiImplicitParams注解中 ,指定一个请求参数的各个方面 |
@ApiResponses | 用在请求的方法(controller类的方法) 上,表示一组响应 |
@ApiResponse | 用在@ApiResponses注解中 ,用于表达一个的响应信息 |
@ApiIgnore | 用于类或者方法(controller类的方法或controller类) 上,可以不被swagger显示在页面上 |
@ApiParam | 作用在参数、方法和字段(cotroller类的方法参数) 上,类似@ApiImplicitParam |
其中@ApiParam和@ApiImplicitParam的功能是相同的,但是@ApiImplicitParam的适用范围更广
@ApiImplicitParam:用在 @ApiImplicitParams 注解中,指定一个请求参数的配置信息
name:参数名
value:参数的汉字说明、解释
required:参数是否必须传
paramType:参数放在哪个地方
· header --> 请求参数的获取:@RequestHeader
· query --> 请求参数的获取:@RequestParam
· path(用于restful接口)--> 请求参数的获取:@PathVariable
· body(不常用)
· form(不常用)
dataType:参数类型,默认String,其它值dataType="Integer"
defaultValue:参数的默认值
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
@ApiParam 作用在参数、方法和字段上
name:参数名称,参数名称将从 filed/method/parameter 名称中派生,但你可以覆盖它,路径参数必须始终命名为它们所代表的路径部分
value:参数简单描述
defaultValu:描述参数默认值
allowableValues:可接收参数值限制,有三种方式,取值列表,取值范围
required:是否为必传参数, false:非必传; true:必传
access:参数过滤,请参阅:io.swagger.core.filter.SwaggerSpecFilter
allowMultiple:指定参数是否可以通过多次出现来接收多个值
hidden:隐藏参数列表中的参数
example:非请求体(body)类型的单个参数示例
example:参数示例,仅适用于请求体类型的请求
type:添加覆盖检测到类型的功能
format:添加提供自定义format格式的功能
allowEmptyValue:添加将格式设置为空的功能
readOnly:添加被指定为只读的能力
collectionFormat:添加使用 array 类型覆盖 collectionFormat 的功能
--------------------------javabean类-------------------------
@ApiModel(value = "User", description = "用户")
public class User implements Serializable{
private static final long serialVersionUID = 1546481732633762837L;
/**
* 用户ID
*/
@ApiModelProperty(value = "用户ID", required = true)
@NotEmpty(message = "{id.empty}", groups = {Default.class,New.class,Update.class})
protected String id;
/**
* code/登录帐号
*/
@ApiModelProperty(value = "code/登录帐号")
@NotEmpty(message = "{itcode.empty}", groups = {Default.class,New.class,Update.class})
protected String itcode;
/**
* 用户姓名
*/
@ApiModelProperty(value = "用户姓名")
@NotEmpty(message = "{name.empty}", groups = {Default.class,New.class,Update.class})
protected String name;
}
--------------------------------controller类-------------------------------
@Api
@controller
public class UserController{
@ApiOperation(value = "获取图书信息", notes = "获取图书信息", response = Book.class, responseContainer = "Item", produces = "application/json")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "book's name", required = true, dataType = "Long", paramType = "query"),
@ApiImplicitParam(name = "date", value = "book's date", required = false, dataType = "string", paramType = "query")})
@ApiResponses(value = {
@ApiResponse(code = 500, message = "2001:因输入数据问题导致的报错"),
@ApiResponse(code = 500, message = "403:没有权限"),
@ApiResponse(code = 500, message = "2500:通用报错(包括数据、逻辑、外键关联等,不区分错误类型)")})
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
@ResponseBody
public Book getBook(@PathVariable Long id, String date) {
return books.get(id);
}
}
swagger皮肤拓展:
默认的:
访问 http://localhost:8080/swagger-ui.html<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.9.2version>
dependency>
bootstrap-ui:
访问 http://localhost:8080/doc.html
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>swagger-bootstrap-uiartifactId>
<version>1.9.1version>
dependency>
Layui-ui :
访问 http://localhost:8080/docs.html
<dependency>
<groupId>com.github.caspar-chengroupId>
<artifactId>swagger-ui-layerartifactId>
<version>1.1.3version>
dependency>
mg-ui :
访问 http://localhost:8080/document.html
<dependency>
<groupId>com.zyplayergroupId>
<artifactId>swagger-mg-uiartifactId>
<version>1.0.6version>
dependency>
Knife4j介绍:
功能预览:
使用简介:
---老版本引用------
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>swagger-bootstrap-uiartifactId>
<version>1.9.6version>
dependency>
------新版本引用-----
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-spring-uiartifactId>
<version>${lastVersion}version>
dependency>
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-spring-boot-starterartifactId>
<version>${knife4j.version}version>
dependency>
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-micro-spring-boot-starterartifactId>
<version>${knife4j.version}version>
dependency>
---------在网关聚合文档服务下,可以再把前端的ui资源引入------------
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-spring-boot-starterartifactId>
<version>${knife4j.version}version>
dependency>
总结:
OpenAPI 是什么?
Swagger2已经在17年停止维护了,取而代之的是 Swagger3(基于OpenApi3)。
RESTful API 是什么?
Swagger 是什么?
四类api :
什么是oauth?
什么是openid?
什么是Mashup?
OpenAPI规范:
OpenAPI规范始于Swagger规范
,经过Reverb Technologies和SmartBear等公司多年的发展,OpenAPI计划拥有该规范(捐赠之后),OpenAPI Initiative在GitHub上托管社区驱动的规范。什么是API优先开发?
API-First如何使您的组织受益?
OpenAPI文档的剖析:
SpringFox:
SpringDoc: