'How to get SpringDoc OpenAPI to work with Servlets?

In my actual project, I exclude a couple packages with endpoints from the main ComponentScan. Instead, each one gets its own ServletRegistrationBean. This way they can all have their own JSON serialization configuration beans.

But if I do this, then SpringDoc does not detect any of my endpoints.

I'm using spring-boot 2.6.4 and springdoc-openapi-ui 1.6.6

package com.example;

@SpringBootApplication(scanBasePackages = "com.example")
@ComponentScan(basePackages = "com.example", excludeFilters = {
    @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.example.demo.*")
})
public class DemoApplication {

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }

  @Bean
  public ServletRegistrationBean<DispatcherServlet> api(ApplicationContext parent) {
    return createChildServlet(
        Arrays.asList("/api/*"),
        DemoApiConfig.class,
        "api",
        parent);
  }

  private ServletRegistrationBean<DispatcherServlet> createChildServlet(List<String> urlMappings,
      Class<?> configuration, String servletRegistrationBeanName, ApplicationContext parent) {

    var applicationContext = new AnnotationConfigWebApplicationContext();
    applicationContext.register(configuration);
    applicationContext.setParent(parent);
    var dispatcherServlet = new DispatcherServlet(applicationContext);
    var servletRegistrationBean = new ServletRegistrationBean<>(dispatcherServlet,
        urlMappings.toArray(new String[] {}));
    servletRegistrationBean.setName(servletRegistrationBeanName);
    servletRegistrationBean.setLoadOnStartup(1);
    return servletRegistrationBean;
  }

}

I've verified that this bean does get created, it just doesn't seem to be used.

package com.example.demo;

@EnableWebMvc
@Configuration
@ComponentScan
public class DemoApiConfig {
}
package com.example.demo;

@RestController
@RequestMapping("/demo/v1")
public class DemoController {
  @Operation(summary = "Demo documentation")
  @GetMapping("/test")
  public ResponseEntity<String> test() {
    return ResponseEntity.ok("Test");
  }
}

If I remove the ComponentScan filter, then the endpoint exists twice as /api/demo/v1/test and /demo/v1/test, and springdoc only detects /demo/v1/test).

With the ComponentScan filter, only /api/demo/v1/test exists and springdoc does not detect it.

How do I get SpringDoc to detect endpoints that exist only inside Servlets?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source