java - Springfox 3.0.0 is not working with Spring Boot 2.6.0

ID : 131322

viewed : 7

Tags : javaspring-bootswaggerspringfoxspring-boot-2.6.0java

Top 5 Answer for java - Springfox 3.0.0 is not working with Spring Boot 2.6.0

vote vote

97

Only adding @EnableWebMvc in main class resolved the problem:

@EnableWebMvc @SpringBootApplication public class MyApp {     public static void main(String[] args) {         SpringApplication.run(MyApp.class);     } } 
vote vote

83

I know this does not solve your problem directly, but consider moving to springdoc which most recent release supports Spring Boot 2.6.0. Springfox is so buggy at this point that is a pain to use. I've moved to springdoc 2 years ago because of its Spring WebFlux support and I am very happy about it. Additionally, it also supports Kotlin Coroutines, which I am not sure Springfox does.

If you decide to migrate, springdoc even has a migration guide.

vote vote

70

Up to now, Springfox 3.0.0 only works with Spring 2.6.0-M2 but not with versions above. See the open Springfox issue https://github.com/springfox/springfox/issues/3462. There you will also find some workarounds you may use until the issue is fixed.

E.g. add this Bean to your Swagger configuration:

@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 <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {             List<T> copy = mappings.stream()                 .filter(mapping -> mapping.getPatternParser() == null)                 .collect(Collectors.toList());             mappings.clear();             mappings.addAll(copy);         }          @SuppressWarnings("unchecked")         private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {             try {                 Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");                 field.setAccessible(true);                 return (List<RequestMappingInfoHandlerMapping>) field.get(bean);             } catch (IllegalArgumentException | IllegalAccessException e) {                 throw new IllegalStateException(e);             }         }     }; } 

EDIT: The server starts, but no API info is returned:

No operations defined in spec!

What a mess.

EDIT 2: As mentioned by @Héctor, spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER must be added to application.properties as well, and the operations are displayed again. However, I don't know, if setting this property is possible in any cases, as it may interfere with other constraints.

vote vote

65

for springfox 3.0.0 and springboot 2.6.1 use this config and add this tag @Configuration @EnableWebMvc

public class SpringFoxConfig {      @Bean     public Docket api() {         return new Docket(DocumentationType.SWAGGER_2)                 .select()                 .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))                 .paths(PathSelectors.any())                 .build().apiInfo(getApiInfo());     }          private ApiInfo getApiInfo() {         return new ApiInfo(                 "Api Usuarios",                 "prueba global logic",                 "1",                 "TERMS OF SERVICE URL",                 new Contact("Gabriel Hernández","URL","gabriel.hernandez.u@gmail.com"),                 "LICENSE",                 "LICENSE URL",                 Collections.emptyList()         );     }          @Bean     public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {         return new BeanPostProcessor() {              @Override             public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {                 if (bean instanceof WebMvcRequestHandlerProvider ) {                     customizeSpringfoxHandlerMappings(getHandlerMappings(bean));                 }                 return bean;             }              private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {                 List<T> copy = mappings.stream()                     .filter(mapping -> mapping.getPatternParser() == null)                     .collect(Collectors.toList());                 mappings.clear();                 mappings.addAll(copy);             }              @SuppressWarnings("unchecked")             private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {                 try {                     Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");                     field.setAccessible(true);                     return (List<RequestMappingInfoHandlerMapping>) field.get(bean);                 } catch (IllegalArgumentException | IllegalAccessException e) {                     throw new IllegalStateException(e);                 }             }         };     }     } 
vote vote

53

A possible solution is to:

1- Set up spring.mvc.pathmatch.matching-strategy: ant_path_matcher in application.properties

2- Add the following bean to your SwaggerConfig class:

@Bean public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {         List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();         Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();         allEndpoints.addAll(webEndpoints);         allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());         allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());         String basePath = webEndpointProperties.getBasePath();         EndpointMapping endpointMapping = new EndpointMapping(basePath);         boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);         return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);     }   private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {         return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));     } 

Credits to hhhhsw

Top 3 video Explaining java - Springfox 3.0.0 is not working with Spring Boot 2.6.0

Related QUESTION?