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
<code><!-- 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></code>Step 2: Configure Properties and Swagger Bean
Add a flag to
application.propertiesto enable Swagger (remember to disable in production):
<code># Control whether Swagger is enabled; set false in production
springfox.swagger2.enabled = true</code>Create a Swagger configuration class:
<code>@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();
}
}
</code>The call to
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))tells Swagger to generate documentation for classes annotated with
@Api.
Step 3: Annotate Controllers and Models
<code>@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";
}
}
</code>Use
@Apion the controller and
@ApiOperationon each endpoint to describe the API. The model class should also be annotated:
<code>@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
}
</code>When a global
ResponseBodyAdvicewraps responses, Swagger UI may fail to parse the JSON. Restrict the advice to your own packages:
<code>@RestControllerAdvice(basePackages = "com.jianzh5.blog")
@Slf4j
public class ResponseAdvice implements ResponseBodyAdvice<Object> {
// implementation
}
</code>After restarting the application, access
http://localhost:8080/swagger-ui.htmlto view the generated documentation.
Swagger UI Beautification with Knife4j
Swagger’s default UI is plain. Enhance it with Knife4j:
Step 1: Add Knife4j Dependency
<code><!-- Integrate Knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
</code>Knife4j already brings in swagger-annotations and swagger-models , so you can remove the manual dependencies added earlier.
Step 2: Enable Knife4j
<code>@Configuration
@EnableSwagger2
@ConditionalOnClass(Docket.class)
@EnableKnife4j
public class SwaggerConfig {
// existing beans
}
</code>Visit
http://localhost:8080/doc.htmlto 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.
<code>@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";
}
</code>Both endpoints use the same
ValidVObut different validation groups, resulting in distinct parameter sets in the generated docs.
To enable grouping, register the following beans in your Swagger configuration:
<code>@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 brevity
</code>Annotate model fields with validation groups and
@ApiModelPropertyto control visibility:
<code>@Null(groups = ValidGroup.Crud.Create.class)
@NotNull(groups = ValidGroup.Crud.Update.class, message = "应用ID不能为空")
@ApiModelProperty(value = "应用ID", example = "cloud")
private String appId;
</code>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.
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.