1 - introduce Maven dependency
👇 Click here to expand the code 👇<properties> <spring-boot.version>2.4.3</spring-boot.version> <spring.version>5.3.4</spring.version> <mybatis.starter.version>2.0.1</mybatis.starter.version> <swagger.version>3.0.0</swagger.version> <knife4j.version>3.0.3</knife4j.version> <slf4j.version>1.7.25</slf4j.version> <log4j.version>1.2.17</log4j.version> </properties> <dependencies> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger.version}</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${swagger.version}</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-boot-starter</artifactId> <version>${swagger.version}</version> <exclusions> <exclusion> <artifactId>guava</artifactId> <groupId>com.google.guava</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>${knife4j.version}</version> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-annotations</artifactId> <version>${knife4j.version}</version> </dependency> <!-- Log frame --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> </dependencies>
2 - write SwaggerConfig configuration class
Note: this configuration class should be placed on the outermost side. It is in the same package as the SpringBoot startup class and cannot be a sub package. Otherwise, there may be some strange problems.
In addition, in swagger version 3. X, the enable OpenAPI annotation is used instead of the enable swagger2 annotation.
👇 Click here to expand the code 👇import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.oas.annotations.EnableOpenApi; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; /** * Swagger API Document configuration * When integrated into SpringBoot, it should be placed in the same level directory of the SpringBoot startup class */ @Configuration @EnableOpenApi public class Swagger2Config { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .enable(true) // Default on .select() .apis(RequestHandlerSelectors.basePackage("com.healchow.swagger.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("HealChow Swagger Doc") .description("More on:< https://healchow.com>") .version("1.0") .build(); } }
3 - Swagger common notes
To be added...
4 - after starting the project, visit the Swagger home page and the Whitelabel Error Page appears

@Configuration @ComponentScan public class ApplicationConfig extends WebMvcConfigurationSupport implements ServletContextInitializer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // Interceptors are defined below, which will invalidate the spring.resources.static-locations configuration registry.addResourceHandler("/**").addResourceLocations("classpath:/webapp/public/"); // Configure knife4j document resource access path registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); } @Override public void addInterceptors(InterceptorRegistry registry) { try { // Set ThreadLocal interceptor registry.addInterceptor(threadLocalInterceptor()).addPathPatterns("/**") .excludePathPatterns("/login/**").excludePathPatterns("/"); super.addInterceptors(registry); } catch (Exception e) { LOGGER.error("Add ThreadLocal Interceptor error", e); } } }
4 - pit Guide
4.1 none of the interfaces in the controller are displayed
On the Controller class, use the annotation @ Api(tags = "public interface (upload / download)") to identify the functions of the current Controller. The value of tags contains a backslash, so that the interface details cannot be displayed:

After changing to @ Api(tags = "public interface (upload, download)"), the display is normal:

4.2 incomplete display of interfaces in some controllers
If the request parameter is a complex type other than the basic Java type, such as HttpServletRequest, then @ ApiImplicitParam cannot be used to describe the parameter information, such as the following:
@ApiOperation(value = "Number of query data") @ApiImplicitParam(name = "request", value = "The request body has the following parameters: startTime,endTime,Format: yyyyMMddHHmm", required = true) public Response<Integer> getDataCount(HttpServletRequest request) { }
You can see in the log that there is a null pointer exception, which may be caused by not specifying dataTypeClass. If you know the reason, thank you for leaving a message to tell me 🤝
Finally, delete @ ApiImplicitParam and change it to the following to display it all:
@ApiOperation(value = "Query the number of data pieces. The request parameters are: startTime,endTime,Format: yyyyMMddHHmm") public Response<Integer> getDataCount(HttpServletRequest request) { }
4.3 when debugging the page, prompt "xx parameter cannot be empty"
For variables in the path (identified by @ PathVariable annotation), even if required = false is not specified, the Swagger page will display the id, which cannot be empty:

@GetMapping("/getDetail/{id}") @ApiOperation(value = "Query details") @ApiImplicitParam(name = "id", value = "data ID", dataTypeClass = String.class, required = false) public Response<Object> getDetail(@PathVariable(required = false) String id) { }
To avoid this situation, you can change this parameter to @ RequestParam as follows:
@GetMapping("/getDetail") @ApiOperation(value = "Query details") @ApiImplicitParam(name = "id", value = "data ID", dataTypeClass = String.class, required = false) public Response<Object> getDetail(@RequestParam(required = false) String id) { }
reference material
https://blog.csdn.net/sanyaoxu_2/article/details/80555328
https://zhuanlan.zhihu.com/p/21353795
https://juejin.cn/post/6844903607414816775
https://www.cnblogs.com/paddix/p/8204916.html
https://juejin.cn/post/6844903993890586632
Copyright notice
Author: Thin wind( https://healchow.com)
source: Blog Garden - south wall of thin wind( https://www.cnblogs.com/shoufeng)
Thank you for reading, official account. "South wall of thin wind" , reading on the mobile phone is better, and there are other benefits and experience output. Welcome to scan the code and pay attention 🤝
The copyright of this article belongs to the blogger. You are welcome to reprint it, but [the original link must be marked in an obvious position on the page], otherwise the blogger reserves the right to investigate the legal liability of relevant persons.