SpringDoc vs Swagger: Complete Spring Boot API Documentation Migration Guide

This tutorial explains why SpringDoc replaces the deprecated SpringFox for Spring Boot 2.6+/3.x, demonstrates zero-config setup with springdoc-openapi-starter-webmvc-ui 2.5.0, covers programmatic and declarative API grouping via GroupedOpenApi beans or YAML, and shows how to resolve static resource conflicts with WebMvcConfigurer and SpringSecurity permitAll rules for /swagger-ui/**, /v3/api-docs/**, and /webjars/**.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
SpringDoc vs Swagger: Complete Spring Boot API Documentation Migration Guide

What Is SpringDoc

SpringDoc is a library built for Spring Boot that automatically generates API documentation compliant with the OpenAPI 3 specification. It scans controllers, method annotations, and configurations at runtime to produce JSON, YAML, or HTML docs and bundles Swagger UI for interactive browsing and testing.

Relationship with Swagger

Swagger originated the OpenAPI specification and provides Swagger UI for rendering. SpringDoc is not a replacement for Swagger; it is an OpenAPI 3 implementation that embeds Swagger UI as its default visualization layer.

Why SpringDoc Over SpringFox

SpringFox was the prior Spring ecosystem integration for Swagger. It performed runtime scanning of @RestController, @RequestMapping, and Swagger-specific annotations like @ApiOperation, emitted Swagger 2.0 or OpenAPI 3.0 JSON, and exposed a Docket configuration class for customizing scan paths and metadata. Swagger UI then consumed that JSON at /swagger-ui.html.

Around 2020 SpringFox maintenance effectively stopped. It cannot adapt to Spring Boot 2.6+ or 3.x (JDK 17+), causing path-matching failures and annotation incompatibilities. SpringDoc fills the gap: it supports Spring Boot 2.6+/3.x natively, adheres to OpenAPI 3 out of the box, requires only a single dependency for zero-config usage, and leverages standard JSR-303 annotations such as @Schema and @Parameter instead of SpringFox-proprietary ones like @ApiModel, reducing learning overhead.

Minimal Setup

Step 1: Add Dependency

<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
  <version>2.5.0</version>
</dependency>

Step 2: Configuration Defaults (Optional)

Without any YAML, SpringDoc scans the entire classpath for @RestController and @RequestMapping. Key defaults:

springdoc:
  packages-to-scan: com.example.controller  # default: full classpath
  swagger-ui:
    enabled: true
    path: /swagger-ui/index.html
    url: /v3/api-docs
    disable-swagger-default-url: false
  api-docs:
    enabled: true
    path: /v3/api-docs

Step 3: Basic Info Configuration Class

@Configuration
@OpenAPIDefinition(info = @Info(
  title = "项目API文档",
  version = "1.0",
  description = "SpringBoot项目接口文档"
))
public class SpringDocConfig {}

Step 4: Access and Annotate

Visit http://localhost:8080/swagger-ui/index.html. Without controllers the page is empty. Adding OpenAPI annotations enriches the output:

@RestController
@RequestMapping("/main")
@Tag(name = "演示controller", description = "演示controller")
public class MainController {
  @GetMapping("/index")
  @Operation(summary = "演示方法", description = "演示方法的注释")
  public String index(@Parameter(description = "参数1", required = true) String str1) {
    return "请求成功";
  }
}

Unannotated endpoints show only path and method; annotated ones display summaries, descriptions, and parameter metadata.

API Grouping

Grouping separates endpoints into named categories in the UI dropdown.

Programmatic Configuration (High Flexibility)

@Configuration
@OpenAPIDefinition(info = @Info(title = "项目API文档", version = "1.0", description = "SpringBoot项目接口文档"))
public class SpringDocConfig {
  @Bean
  public GroupedOpenApi defaultGroup() {
    return GroupedOpenApi.builder()
      .group("默认分组")
      .pathsToMatch("/**")
      .build();
  }
  @Bean
  public GroupedOpenApi userGroup() {
    return GroupedOpenApi.builder()
      .group("商品模块")
      .pathsToMatch("/api/product/**")
      .build();
  }
  @Bean
  public GroupedOpenApi productGroup() {
    return GroupedOpenApi.builder()
      .group("用户模块")
      .packagesToScan("com.ren.main.controller.member")
      .build();
  }
}

Rules: once any GroupedOpenApi bean exists, springdoc.packages-to-scan in YAML is ignored because group scan paths take precedence. Two scan modes exist — path matching ( pathsToMatch) and package scanning ( packagesToScan). Overlapping paths cause an endpoint to appear in multiple groups.

The author's project structure includes MainController, ProductController under /api/product/**, and MemberController under com.ren.main.controller.member. Without a default group, MainController disappears because group config overrides global scan. Adding a default group with pathsToMatch("/**") restores it; overlapping endpoints then show in both their specific group and the default group.

Declarative Configuration (Centralized, Environment-Isolated)

springdoc:
  group-configs:
    - group: '默认分组'
      paths-to-match: '/**'
    - group: '商品模块'
      paths-to-match: '/api/product/**'
    - group: '用户模块'
      packages-to-scan: 'com.ren.main.controller.member'

Produces identical UI grouping.

Handling WebMvcConfigurer.addResourceHandlers Override

WebMvcConfigurer

customizes Spring MVC behavior (interceptors, CORS, static resources, view controllers, message converters, path matching, argument/return-value handlers, content negotiation). Overriding addResourceHandlers disables all default static resource mappings, including SpringDoc's Swagger UI assets. Restore them explicitly:

@Configuration
public class ResourcesConfig implements WebMvcConfigurer {
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/swagger-ui/**")
      .addResourceLocations("classpath:/META-INF/resources/webjars/springdoc-openapi-ui/")
      .setCacheControl(CacheControl.maxAge(5, TimeUnit.HOURS).cachePublic());
  }
}

Note: SpringDoc 2.x resource path differs from legacy SpringFox.

SpringSecurity Integration

SpringSecurity blocks unauthenticated access by default. Permit SpringDoc endpoints in the filter chain:

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
public class SecurityConfig {
  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(auth -> auth
      .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
      .requestMatchers(request -> {
        String path = request.getServletPath();
        return request.getMethod().equals("GET") && (
          "/".equals(path) || path.endsWith(".html") || path.endsWith(".css") || path.endsWith(".js"));
      }).permitAll()
      .requestMatchers(
        "/swagger-ui/**",
        "/*/api-docs/**",
        "/swagger-resources/**",
        "/webjars/**",
        "/druid/**"
      ).permitAll()
      .anyRequest().authenticated()
    );
    return http.build();
  }
}

This opens Swagger UI, the OpenAPI docs endpoint, Swagger resources, WebJars, and (optionally) Druid console while keeping all other requests secured.

Summary

The article walks through SpringDoc adoption from rationale to production-ready configuration: zero-dependency start, annotation-driven metadata, two grouping strategies with precedence rules, static resource handler conflict resolution, and SpringSecurity permit lists. All code targets SpringDoc 2.5.0 on Spring Boot 3.x.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Spring BootAPI DocumentationWebMvcConfigurerSpringDocSpringSecuritySwagger UIGroupedOpenApiOpenAPI 3
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.