Master Swagger Integration in SpringBoot: Step-by-Step Guide & Advanced Features
This article walks through integrating Swagger into a SpringBoot project, covering dependency setup, configuration, handling common issues like ResponseBodyAdvice conflicts, enhancing UI with Knife4j, and leveraging Swagger’s grouping feature for parameter validation, providing complete code snippets and troubleshooting tips for seamless API documentation.
Why Use Swagger?
As programmers we hate two things: 1) others not writing comments, 2) writing comments ourselves. As API developers we also hate: 1) missing or outdated interface docs, 2) having to write and keep them up‑to‑date.
Both front‑end and back‑end developers have been tormented by inconsistent or stale API documentation. With the rise of SpringBoot, SpringCloud and micro‑services, projects may have hundreds of endpoints, making manual docs impractical. Swagger automates doc generation and keeps them in sync.
Swagger offers four major benefits:
Automatic documentation generation with minimal annotations.
Cross‑language support for over 40 languages.
Interactive UI allowing API calls directly from the doc page.
Exportable specifications that can be consumed by tools such as SoapUI for automated testing.
Swagger Integration
Integrating Swagger is straightforward and can be done in three steps.
Step 1: Add Dependencies
<!-- swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- swagger‑ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>Step 2: Configure Properties and Swagger Bean
Add a flag to application.properties to enable Swagger (remember to disable in production):
# Control whether Swagger is enabled; set false in production
springfox.swagger2.enabled = trueCreate a Swagger configuration class:
@Configuration
@EnableSwagger2
@ConditionalOnClass(Docket.class)
public class SwaggerConfig {
private static final String VERSION = "1.0";
@Value("${springfox.swagger2.enabled}")
private Boolean swaggerEnabled;
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.enable(swaggerEnabled)
.groupName("SwaggerDemo")
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.any())
.build();
}
/** Add API meta information */
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("接口文档")
.contact(new Contact("JAVA日知录", "http://javadaily.cn", "[email protected]"))
.description("Swagger接口文档")
.version(VERSION)
.build();
}
}The call to
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))tells Swagger to generate documentation for classes annotated with @Api.
Step 3: Annotate Controllers and Models
@RestController
@Api(tags = "参数校验")
@Slf4j
@Validated
public class ValidController {
@PostMapping("/valid/test1")
@ApiOperation("RequestBody校验")
public String test1(@Validated @RequestBody ValidVO validVO) {
log.info("validEntity is {}", validVO);
return "test1 valid success";
}
@PostMapping("/valid/test2")
@ApiOperation("Form校验")
public String test2(@Validated ValidVO validVO) {
log.info("validEntity is {}", validVO);
return "test2 valid success";
}
@PostMapping("/valid/test3")
@ApiOperation("单参数校验")
public String test3(@Email String email) {
log.info("email is {}", email);
return "email valid success";
}
}Use @Api on the controller and @ApiOperation on each endpoint to describe the API. The model class should also be annotated:
@Data
@ApiModel(value = "参数校验类")
public class ValidVO {
@ApiModelProperty("ID")
private String id;
@ApiModelProperty(value = "应用ID", example = "cloud")
private String appId;
@NotEmpty(message = "级别不能为空")
@ApiModelProperty(value = "级别")
private String level;
@ApiModelProperty(value = "年龄")
private int age;
// ... other fields
}When a global ResponseBodyAdvice wraps responses, Swagger UI may fail to parse the JSON. Restrict the advice to your own packages:
@RestControllerAdvice(basePackages = "com.jianzh5.blog")
@Slf4j
public class ResponseAdvice implements ResponseBodyAdvice<Object> {
// implementation
}After restarting the application, access http://localhost:8080/swagger-ui.html to view the generated documentation.
Swagger UI Beautification with Knife4j
Swagger’s default UI is plain. Enhance it with Knife4j:
Step 1: Add Knife4j Dependency
<!-- Integrate Knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>Knife4j already brings in swagger-annotations and swagger-models , so you can remove the manual dependencies added earlier.
Step 2: Enable Knife4j
@Configuration
@EnableSwagger2
@ConditionalOnClass(Docket.class)
@EnableKnife4j
public class SwaggerConfig {
// existing beans
}Visit http://localhost:8080/doc.html to see the enhanced UI.
Swagger Parameter Grouping
Swagger 2 does not support parameter groups out of the box. By extending Swagger you can show different fields for create vs. update operations.
@ApiOperation("新增")
@PostMapping("/valid/add")
public String add(@Validated(value = {ValidGroup.Crud.Create.class}) ValidVO validVO) {
log.info("validEntity is {}", validVO);
return "test3 valid success";
}
@ApiOperation("更新")
@PostMapping("/valid/update")
public String update(@Validated(value = ValidGroup.Crud.Update.class) ValidVO validVO) {
log.info("validEntity is {}", validVO);
return "test4 valid success";
}Both endpoints use the same ValidVO but different validation groups, resulting in distinct parameter sets in the generated docs.
To enable grouping, register the following beans in your Swagger configuration:
@Bean
@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
public GroupOperationModelsProviderPlugin groupOperationModelsProviderPlugin() {
return new GroupOperationModelsProviderPlugin();
}
@Bean
@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000)
public GroupModelBuilderPlugin groupModelBuilderPlugin() {
return new GroupModelBuilderPlugin();
}
// additional beans omitted for brevityAnnotate model fields with validation groups and @ApiModelProperty to control visibility:
@Null(groups = ValidGroup.Crud.Create.class)
@NotNull(groups = ValidGroup.Crud.Update.class, message = "应用ID不能为空")
@ApiModelProperty(value = "应用ID", example = "cloud")
private String appId;Conclusion
Integrating Swagger into a SpringBoot project is simple, and the tool greatly eases API documentation maintenance. The article highlighted the grouping feature, which avoids creating multiple DTOs for different operations. Note that the presented grouping extensions work with Swagger 2; Swagger 3 requires a different approach.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
