In our work, when we develop some APIs, we usually need to provide a corresponding interface document after completion, so we need to spend a certain amount of time and effort to complete the numbering of interface documents and write In the interface document, as the requirements change and the optimization and advancement of the project, the details of the interface are constantly evolving, and the interface description document also needs to be revised synchronously, which is very troublesome, so we can adopt the automatic document generation mode: swagger2, RAP, etc .
Here we mainly introduce the basic usage of a Swagger2. Swagger2 can automatically generate powerful restful API documents with the project to reduce the workload. The API documents are integrated with the code to facilitate the simultaneous update of API descriptions, and provide a page test function to debug each restful API.
First of all, when using Swagger2, the first thing we need to do is to introduce related dependencies, as follows:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
Then we need to add a Swagger2 configuration class, as follows:
@Configuration
@EnableSwagger2
public class Swagger2Config {
//api接口包扫描路径
public static final String SWAGGER_SCAN_BASE_PACKAGE = "com.kimi";
//api接口文档版本信息
public static final String VERSION = "1.0.0";
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//为指定包下Controller生成API文档
.apis(RequestHandlerSelectors.basePackage(SWAGGER_SCAN_BASE_PACKAGE))
.paths(PathSelectors.any())
.build();
}
//创建api的基本信息
private ApiInfo apiInfo() {
Contact contact = new Contact("Kimi", "www.kimi0107.com", "[email protected]");
return new ApiInfoBuilder()
//设置文档的标题
.title("集成Swagger2构建API文档")
//设置文档的描述
.description("SpringBoot集成Swagger2构建restful API文档")
//设置文档的License信息
.termsOfServiceUrl("http://www.kimi0107.com/")
//设置文档的联系信息
.contact(contact)
//设置文档的版本信息
.version(VERSION)
.build();
}
}
As shown in the code above, through @Configuration
annotations, let Spring load the configuration class. Use @EnableSwagger2
annotations to enable Swagger2. After the member method createRestApi function creates a Docket bean, apiInfo () is used to create the basic information of the API (these basic information will be displayed on the document page).
The select () function returns an ApiSelectorBuilder instance to control which interfaces are exposed to Swagger for display. In this example, the specified scan package path is used to define. Swagger will scan all APIs defined by the Controller under the package and generate document content (except for the @ApiIgnore
specified Request).
Of course, we process the specified scan package path to define the interface that generates the interface document, and there are other ways. The common methods are as follows
After completing the above configuration, the content of the document can actually be generated, but such a document is mainly for the request itself, and the description is mainly derived from the naming of the function and the like, which is not friendly to the user, start the project, accesshttp://localhost:8080/swagger-ui.html, The interface is as follows:
As you can see from the screenshot above, the interface is already very powerful, and we can also test it directly, but in actual use, we can also add some instructions to enrich the content of the document, which is more common @ApiOperation
and @ApiImplicitParam
two comments. ,as follows:
In addition, if the method contains multiple parameters, we can use @ApiImplicitParams
it instead @ApiImplicitParam
, and its usage is very simple, that is, a @ApiImplicitParam
parameter that can contain multiple arrays
But sometimes we often use to the entity class to pass argument, here we need to use @ApiModel
and @ApiModelProperty
, annotated instructions on the use to the entity classes, as follows:
There are also some notes that we often use in our work, as follows:
@Api
@Api (tags = "" Describe the role of this class ", value =" "The parameter is meaningless, generally do not configure")
Decorate the entire class and place it on the requested class, juxtaposed with @Controller to explain the role of the class, such as user module API, order module API, etc.
@ApiOperation
@ApiOperation (value = "" Describe the role of the method ", notes =" "Remarks of the method")
@ApiImplicitParams 、@ApiImplicitParam
@ApiImplicitParam:
A description of a single parameter
@ApiImplicitParams:
used in the method of request, contains a set of parameter descriptions
@ApiImplicitParams ({
@ApiImplicitParam (name = “id”, value = “user ID”, required = true, paramType = “form”),
@ApiImplicitParam (name = “name”, value = “user name”, required = true , ParamType = “form”),
@ApiImplicitParam (name = “age”, value = “user age”, required = true, paramType = “form”, dataType = “Integer”)
})
name: parameter name
value: parameter Explanation and explanation of Chinese characters
required: whether the parameter must be passed
paramType: where to put the parameter header-
> request parameter acquisition: @RequestHeader query-
> request parameter acquisition: @RequestParam
path (for restful interface)-> request parameter Get: @PathVariable
body (Request body) –> @RequestBody User user
form (general form submission)
dataType: parameter type, default String, other values dataType = “int”
defaultValue: default value of parameter
@ApiResponses 、 @ ApiResponse
@ApiResponses:
Method returns a description of the object
@ApiResponse:
description of each parameter
@ApiResponses ({
@ApiResponse (code = 400, message = "Request parameters not
filled in "), @ApiResponse (code = 404, message = "Request path not found")
})
code: number, for example 400
message: message , For example "request parameter not filled in"
response: class that throws an exception
@ApiIgnore
Use annotations to ignore this API and not participate in document generation
@ApiError
Information returned when an error occurs
@ApiProperty
When receiving parameters with an object, describe a field of the object
After integrating the Swagger2 build API document, we may only need to use it in the test environment, but it is required to be closed in the generation environment. Here we can configure the relevant configuration in the SpringBoot.properties file or .yml file, as follows :
swagger.enable=true
swagger:
enable: true
In addition, if we integrate Spring Security in the project, or integrate Shiro and other permissions control, the Swagger2 document will be intercepted without additional configuration. The solution is to add a white list to the relevant configuration class:
For example, you can override the configure method in the Security configuration class:
@Override
public void configure (WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/swagger-ui.html")
.antMatchers("/v2/**")
.antMatchers("/swagger-resources/**");
}
Or as related configuration in Shiro's configuration class, as follows:
//swagger2免拦截
filterChainDefinitionMap.put("/swagger-ui.html**", "anon");
filterChainDefinitionMap.put("/v2/api-docs", "anon");
filterChainDefinitionMap.put("/swagger-resources/**", "anon");
filterChainDefinitionMap.put("/webjars/**", "anon");
Inherited WebMvcConfigurationSupport, rewritten addResourceHandlers method
/**
* 配置swagger2的静态资源路径
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决静态资源无法访问
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/");
// 解决swagger无法访问
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
// 解决swagger的js文件无法访问
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}