Article directory
- foreword
- 1. Introduction
- 2. Basic use
- 3. Advanced use
-
foreword
As a back-end opener, the most annoying thing is to write interface documents by yourself and others have not written interface documents. Whether it is front-end or back-end development, you will be more or less tortured by interface documents. The front-end will complain that the back-end does not update the interface documents in time. , and the backend will find it too troublesome to write interface documents. Swagger can better interact with interface documents, define interfaces and related information with a set of standard specifications, and can generate interface documents in various formats, generate multiple languages and client and server codes, and Online interface debugging page and so on. Only need to update the Swagger description file, the interface document can be automatically generated, so as to achieve the timeliness and convenience of front-end and back-end joint debugging interface documents.
1. Introduction
Official website: https://swagger.io/
Swagger is a standardized and complete framework for generating, describing, invoking, and visualizing RESTful-style Web services.
The goal of Swagger is to define a standard and language-independent interface to the REST API, which allows people and computers to have the ability to discover and understand services without access to source code, documentation, or network traffic monitoring. When properly defined through Swagger, users can understand and interact with remote services with minimal implementation logic. Similar to interfaces implemented for low-level programming, Swagger takes the guesswork out of invoking services.
Advantages of Swagger
- Support API to automatically generate synchronous online documents: After using Swagger, you can directly generate documents through code, no longer need to manually write interface documents, which is very convenient for programmers, and can save the time of writing documents to learn new technologies.
- Provide online testing API for Web pages: documentation alone is not enough, the documentation generated by Swagger also supports online testing. The parameters and format are set, and the interface can be tested online by directly inputting the corresponding value of the parameter on the interface.
2. Basic use
1. Import related dependencies
By introducing Springfox into the project, the related code can be scanned to generate the description file, and then the interface document and client code consistent with the code can be generated.
<!-- swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-spring-web</artifactId> <version>2.9.2</version> </dependency> <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>
2. Write configuration files
In the configuration file config
directory, add the swagger configuration fileSwaggerConfig.java
@Configuration // 配置类
@EnableSwagger2 // 开启 swagger2 的自动配置
public class SwaggerConfig {
}
At this time, Swagger has been integrated into the project. You can start the service and enter: http://localhost:8080/swagger-ui.html#
(here my project port is 8868, and the project path is /mike, so the address of the document I opened is http://localhost:8868/mike/swagger-ui.html#
) to view the swagger document.
You can see that there are about four types of information in the Swagger document
- Group
- Basic Information
- interface information
- Entity class information
2.1 Configure basic information
Swagger has its own instance Docket. If we want to customize the basic information, we can use the docket to configure the basic information of swagger. The basic information is set in ApiInfo
this object.
Swagger default basic information display
Default basic settings in ApiInfo
- title:Api Documentation
- description:Api Documentation
- version:1.0
- termsOfServiceUrl:urn:tos
- contact: none
- license:Apache 2.0
- licenseUrl:http://www.apache.org/licenses/LICENSE-2.0
SwaggerConfig.java
The configuration file adds the following:
@Bean
public Docket docket() {
// 创建一个 swagger 的 bean 实例
return new Docket(DocumentationType.SWAGGER_2)
// 配置基本信息
.apiInfo(apiInfo())
;
}
// 基本信息设置
private ApiInfo apiInfo() {
Contact contact = new Contact(
"米大傻", // 作者姓名
"https://blog.csdn.net/xhmico?type=blog", // 作者网址
"[email protected]"); // 作者邮箱
return new ApiInfoBuilder()
.title("多加辣-接口文档") // 标题
.description("众里寻他千百度,慕然回首那人却在灯火阑珊处") // 描述
.termsOfServiceUrl("https://www.baidu.com") // 跳转连接
.version("1.0") // 版本
.license("Swagger-的使用(详细教程)")
.licenseUrl("https://blog.csdn.net/xhmico/article/details/125353535")
.contact(contact)
.build();
}
Restart the service, open the Swagger document, and the basic information changes as follows:
2.2 Configure interface information
By default, Swagger will display all interface information, including the most basic basic-error
related interfaces
Sometimes we don't want to display basic-error-controller
related interfaces, or we want to display certain interfaces, for example: user-controller
how to implement the following interfaces? At this time, you need to set扫描接口
@Bean
public Docket docket() {
// 创建一个 swagger 的 bean 实例
return new Docket(DocumentationType.SWAGGER_2)
// 配置接口信息
.select() // 设置扫描接口
// 配置如何扫描接口
.apis(RequestHandlerSelectors
//.any() // 扫描全部的接口,默认
//.none() // 全部不扫描
.basePackage("com.duojiala.mikeboot.controller") // 扫描指定包下的接口,最为常用
//.withClassAnnotation(RestController.class) // 扫描带有指定注解的类下所有接口
//.withMethodAnnotation(PostMapping.class) // 扫描带有只当注解的方法接口
)
.paths(PathSelectors
.any() // 满足条件的路径,该断言总为true
//.none() // 不满足条件的路径,该断言总为false(可用于生成环境屏蔽 swagger)
//.ant("/user/**") // 满足字符串表达式路径
//.regex("") // 符合正则的路径
)
.build();
}
You can set the corresponding configuration according to your own needs, so I won’t go into details here. The above is the configuration I set, restart the service, open the Swagger document, and the interface information changes as follows:
You can see that the previous basic-error-controller
related interface is gone
2.3 Configure group information
Swagger has only one default grouping option by default. If it is not set, all interfaces will be displayed under default
the grouping. If there are too many functional modules and interfaces, it will appear messy and inconvenient to find and use.
The group name in the swagger document is by default default
, which can be passed.groupName(String )
@Bean
public Docket docket() {
// 创建一个 swagger 的 bean 实例
return new Docket(DocumentationType.SWAGGER_2)
.groupName("mike") // 修改组名为 "mike"
;
}
After modification:
If you need to configure multiple groups, you need to configure multiple groups docket() 方法
. Here I simply write two groups. The code is as follows:
/**
* 展示 controller 包下所有的接口
*/
@Bean
public Docket docket1() {
// 创建一个 swagger 的 bean 实例
return new Docket(DocumentationType.SWAGGER_2)
.groupName("mike") // 修改组名为 "mike"
// 配置接口信息
.select() // 设置扫描接口
// 配置如何扫描接口
.apis(RequestHandlerSelectors
.basePackage("com.duojiala.mikeboot.controller") // 扫描指定包下的接口,最为常用
)
.paths(PathSelectors
.any() // 满足条件的路径,该断言总为true
)
.build();
}
/**
* 展示路径为 /error 的所有接口(基础接口)
*/
@Bean
public Docket docket2() {
// 创建一个 swagger 的 bean 实例
return new Docket(DocumentationType.SWAGGER_2)
.groupName("yank") // 修改组名为 "yank"
// 配置接口信息
.select() // 设置扫描接口
// 配置如何扫描接口
.apis(RequestHandlerSelectors
.any() // 扫描全部的接口,默认
)
.paths(PathSelectors
.ant("/error") // 满足字符串表达式路径
)
.build();
}
Restart the service, open the Swagger document, and the interface information changes as follows:
There is only relevant interface information mike
in the document with the group nameuser-controller
There is only relevant interface information yank
in the document with the group namebasic-error-controller
3. Control the opening of Swagger
In the development or test environment, we enable swagger to facilitate the interaction between the front end and the back end, but if swagger is also enabled in the production environment, the interface will be exposed, which has great risks. How to make swagger according to different environments Decide whether to enable?
Here I prepared the configuration files of four projects, the configuration files of dev
, , test
and pro
three environments are only different on the port
- application.yml -------------------------- Global configuration file
- application-dev.yml -------------------- development environment configuration file
- application-test.yml -------------------- Test environment configuration file
- application-pro.yml -------------------- production environment configuration file
application.yml
The content is as follows, used to specify the selected environment:
spring:
profiles:
active: dev
You can judge what environment you are in at this time through the code: dev
, test
, pro
, if it is in pro
the production environment, close swagger.
/**
* swagger 配置
* @param environment 环境
*/
@Bean
public Docket docket(Environment environment) {
// 设置环境范围
Profiles profiles = Profiles.of("dev","test");
// 如果在该环境返回内则返回:true,反之返回 false
boolean flag = environment.acceptsProfiles(profiles);
// 创建一个 swagger 的 bean 实例
return new Docket(DocumentationType.SWAGGER_2)
.enable(flag) // 是否开启 swagger:true -> 开启,false -> 关闭
;
}
When the environment points to in application.yml
the global configuration file dev
, swagger can be opened
If I application.yml
point the environment in the global configuration file to pro
, I can’t open swagger, promptingCould not render e, see the console
4. Commonly used annotations
It was said before that Swagger will display interface requests or corresponding entity class information Models
under . For example, I UserController.java
have an interface under :
@PostMapping(value = "/query-user-info")
public ResponseBean queryUserInfo(@RequestBody @Validated IdReq req) {
return ResponseBean.success(userService.queryUserInfo(req));
}
Its request body is IdReq
, the response is ResponseBean
, and Models
the information of these two entity classes is displayed as follows:
The front end can know the information of the entity class defined by the back end by looking at this Models
.
@ApiModel
This annotation acts on the entity class and is used to describe some basic information of the entity class.
Related properties:
value
: Provide an alternate name for the class, if not set, the name of the class class will be used by default- description: For a class, provide a detailed description
- parent: This attribute is used to describe some parent class information of the class
- discriminator: This attribute is more troublesome to explain, because this class is mainly reflected in the assertion
- subTypes: Through this attribute, we can specify the subclass we want to use
For example: this is to IdReq
add this annotation to this class
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "Id请求体")
public class IdReq {
private String id;
}
You can see that the name here has IdReq
changed fromId请求体
@ApiModelProperty
This annotation is used on attributes of entity classes. Its role is to add and manipulate the data of the attribute module.
For details on the use of this annotation, please refer to the blog: Usage of @ApiModelProperty annotation
Here I still take IdReq
the class as an example to add descriptions to the properties of this class
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(value = "Id请求体")
public class IdReq {
@ApiModelProperty("主键id")
private String id;
}
You can see that there is a note for this field here.
@ApiOperation
This annotation is used on methods in the Controller class. Used to describe a method/interface
For details on the use of this annotation, please refer to the blog: Swagger @ApiOperation annotation detailed explanation
Here I take the UserController
following interface as an example:
@PostMapping(value = "/query-user-info")
@ApiOperation(value = "根据id查询用户详情")
public ResponseBean queryUserInfo(@RequestBody @Validated IdReq req) {
return ResponseBean.success(userService.queryUserInfo(req));
}
You can see that the interface has more description information for it.
@ApiParam
This annotation is used on the method or parameter of the Controller class to describe the field and indicate the addition of metadata to the parameter (description or whether it is required, etc.)
Related properties:
- name: parameter name
- value: parameter description
- required: whether it is required
Here I take the UserController
following interface as an example:
@PostMapping(value = "/query-user-infos")
@ApiOperation(value = "条件查询用户信息")
public ResponseBean queryUserInfos(
// name 用户名称 不必填
@ApiParam(value = "用户名称", required = false) @RequestParam(required = false) String name,
// gender 用户性别 必填
@ApiParam(value = "用户性别", required = true) @RequestParam(required = true) GenderEnum gender
) {
return ResponseBean.success(userService.queryUserInfos(name,gender));
}
Here will display the remark information of the request parameters and whether they are required or not.
5. Interface call
Using swagger not only facilitates front-end and back-end interaction, but also makes interface requests simple. You only need to fill in the parameter information required by the request to initiate the request directly.
For example interface/user/query-user-info
clickTry it out
After setting the parameters required for the request, click Execute
Execute
You can see the result of the interface response
The interface /user/query-user-infos
is similar
3. Advanced use
1. Add request header
Sometimes our interface needs to obtain the request header information, so we need to add the configuration of the request header in the swagger configuration.
@Bean
public Docket docket() {
// 设置请求头
List<Parameter> parameters = new ArrayList<>();
parameters.add(new ParameterBuilder()
.name("token") // 字段名
.description("token") // 描述
.modelRef(new ModelRef("string")) // 数据类型
.parameterType("header") // 参数类型
.defaultValue("default value") // 默认值:可自己设置
.hidden(true) // 是否隐藏
.required(false) // 是否必须
.build());
// 创建一个 swagger 的 bean 实例
return new Docket(DocumentationType.SWAGGER_2)
.groupName("mike") // 修改组名为 "mike"
// 配置接口信息
.select() // 设置扫描接口
// 配置如何扫描接口
.apis(RequestHandlerSelectors
.basePackage("com.duojiala.mikeboot.controller") // 扫描指定包下的接口,最为常用
)
.paths(PathSelectors
.any() // 满足条件的路径,该断言总为true
)
.build()
// 添加请求头参数
.globalOperationParameters(parameters);
}
For example interface:
@GetMapping(value = "/get-token")
@ApiOperation(value = "获取请求头中的token信息")
public void getToken(
@RequestHeader(value = "token",required = false) String token
) {
// 直接获取 token 信息
System.out.println("token = " + token);
// 通过代码获取
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (servletRequestAttributes != null) {
HttpServletRequest request = servletRequestAttributes.getRequest();
String header = request.getHeader("token");
System.err.println("header = " + header);
}
}
You can see that this interface can already set the request header, call the interface
The backend is also available.