Using Swagger for API Documentation in Spring Boot: Setup, Configuration, and Customization
This article explains what Swagger is, why it is useful for RESTful API documentation, and provides a step‑by‑step guide for integrating Swagger 3.0 with Spring Boot 2.7.6, handling version conflicts, customizing Docket settings, securing the UI, and applying advanced annotations to enrich the generated documentation.
Swagger is a popular RESTful API documentation tool that automatically generates readable and interactive documentation from code annotations. It helps developers avoid manual doc maintenance and keeps API definitions synchronized with the implementation.
Key advantages of Swagger include automatic generation from annotations, an embedded web UI for testing endpoints, multi‑language support (Java, PHP, Python, etc.), and the ability to focus on coding rather than documentation.
Setup
Add the required Maven dependencies (Swagger 3.0 and Springfox starter) to the project:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>Create a simple controller (e.g., TestController ) with a single endpoint /test :
@RestController
public class TestController {
@RequestMapping("/test")
public String test(String name) {
return name;
}
}Configure Swagger by defining a configuration class annotated with @EnableSwagger2 (or @EnableSwagger for newer versions):
@Configuration
@EnableSwagger2
public class SwaggerConfig {
// additional Docket beans can be defined here
}Common startup error
When using Spring Boot 2.7.x, a conflict may occur between AntPathMatcher (used by Springfox) and PathPatternMatcher (used by Spring Boot). The stack trace looks like:
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(...)
... (additional stack frames) ...Four typical solutions are:
Downgrade Spring Boot to 2.5.x or Springfox to a compatible version.
Force Spring MVC to use the older ant_path_matcher strategy by adding to application.yml : spring: mvc: pathmatch: matching-strategy: ant_path_matcher
Add @EnableWebMvc to the Swagger configuration class.
Register a custom BeanPostProcessor that filters out handler mappings using the new PathPatternParser . @Bean public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() { return new BeanPostProcessor() { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); } return bean; } private void customizeSpringfoxHandlerMappings(List mappings) { List copy = mappings.stream() .filter(m -> m.getPatternParser() == null) .collect(Collectors.toList()); mappings.clear(); mappings.addAll(copy); } private List getHandlerMappings(Object bean) { try { Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); field.setAccessible(true); return (List ) field.get(bean); } catch (Exception e) { throw new IllegalStateException(e); } } }; }
After fixing the issue, the Swagger UI can be accessed at http://127.0.0.1:9002/swagger-ui/index.html , where the documented endpoints are displayed.
Customizing the API documentation
The Docket bean offers many configuration methods:
select() returns an ApiSelectorBuilder to specify which APIs and paths to include.
apis() can filter by base package, e.g., RequestHandlerSelectors.basePackage("com.springboot101.controller") .
paths() can limit to specific URL patterns, e.g., PathSelectors.ant("/test/**") .
groupName() creates separate documentation groups.
apiInfo() sets title, description, version, contact, license, etc. private ApiInfo apiInfo() { Contact contact = new Contact("小富", "http://fire100.top", "[email protected]"); return new ApiInfoBuilder() .title("Swagger学习") .description("程序员小富-带你一起学习 Swagger") .version("v1.0.1") .termsOfServiceUrl("http://fire100.top") .contact(contact) .license("许可证") .licenseUrl("许可链接") .extensions(Arrays.asList( new StringVendorExtension("我是", "小富"), new StringVendorExtension("你是", "谁"))) .build(); }
enable() can turn the documentation on or off based on active Spring profiles.
host() sets the host name displayed in the UI.
securitySchemes() defines authentication methods (Bearer, Authorization, Basic) using ApiKey objects.
securityContexts() links the schemes to specific API paths.
tags() adds custom tags for grouping.
Example of a security scheme configuration:
return new Docket(DocumentationType.SWAGGER_2)
.securitySchemes(Arrays.asList(
new ApiKey("Bearer鉴权", "Bearer", "header"),
new ApiKey("Authorization鉴权", "Authorization", "header"),
new ApiKey("Basic鉴权", "Basic", "header")))
.securityContexts(Collections.singletonList(securityContext()));To protect the UI, add Spring Security dependency and configure a username/password in application.yml :
spring:
security:
user:
name: admin
password: 123456When the UI is accessed, a login page appears.
Documentation annotations
Swagger provides several annotations to enrich the generated docs:
@ApiIgnore – exclude a controller or method.
@ApiModel and @ApiModelProperty – add descriptions to model classes and fields. @ApiModel(value = "用户实体类", description = "用于存放用户登录信息") @Data public class User { @ApiModelProperty(value = "用户名字段", required = true, example = "#公众号:程序员小富") private String name; @ApiModelProperty(value = "年龄", required = true, example = "19") private Integer age; @ApiModelProperty(value = "邮箱", required = true, example = "#公众号:程序员小富") private String email; }
@Api – describe a controller, set tags, protocols, etc.
@ApiOperation – document a specific endpoint (value, notes, httpMethod, response, tags, etc.).
@ApiImplicitParams / @ApiImplicitParam – describe parameters when they cannot be inferred automatically. @ApiImplicitParams({ @ApiImplicitParam(name = "用户名", value = "用户名称信息", required = true, dataType = "String", paramType = "query") }) @GetMapping("/user") public String user(String name) { return name; }
@ApiParam – alternative way to describe a single method parameter.
@ApiResponses / @ApiResponse – list possible HTTP status codes and their meanings. @ApiResponses({ @ApiResponse(code = 200, message = "@ApiResponse注解测试通过", response = String.class), @ApiResponse(code = 401, message = "可能参数填的有问题", response = String.class), @ApiResponse(code = 404, message = "可能请求路径写的有问题", response = String.class) }) @GetMapping("/user4") public String user4(@ApiParam(name = "主键ID", value = "@ApiParam注解测试", required = true) String id) { return id; }
By combining these annotations, developers can produce comprehensive, searchable, and interactive API documentation that greatly improves maintainability and onboarding experience.
Conclusion
Even though Swagger may not be a focus in interviews, adopting a consistent documentation practice is essential for any backend developer. Clear, detailed API docs help teams collaborate effectively and reduce bugs caused by misunderstood contracts.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
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.