Springboot2.6.3不兼容swagger3.0.0问题

记录下 Springboot2.6.3不兼容swagger3.0.0问题

1.springboot版本


  org.springframework.boot
  spring-boot-starter-parent
  2.6.0


2.springfox版本 


        io.springfox
        springfox-boot-starter
        3.0.0
 

spring5支持PathMatchConfigurer导致

Failed to start bean ‘documentationPluginsBootstrapper

启动报错解决方案1:

appliaction.yml  添加配置

spring:
  mvc:
     pathmatch:
          matching-strategy: ant_path_matcher

重写

springfox.documentation.spring.web.WebMvcPatternsRequestConditionWrapper

springfox.documentation.spring.web.WebMvcRequestHandler

两个类;

将PatternsRequestCondition改为PathPatternsRequestCondition;

package springfox.documentation.spring.web;
 
import static springfox.documentation.spring.web.paths.Paths.maybeChompLeadingSlash;
import static springfox.documentation.spring.web.paths.Paths.maybeChompTrailingSlash;
 
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
 
/**
 * swagger3.0兼容springBoot2.6.3处理
 */
public class WebMvcPatternsRequestConditionWrapper
        implements
        springfox.documentation.spring.wrapper.PatternsRequestCondition {
 
    private final String contextPath;
    private final PathPatternsRequestCondition condition;
 
    public WebMvcPatternsRequestConditionWrapper(
            String contextPath,
            PathPatternsRequestCondition condition) {
 
        this.contextPath = contextPath;
        this.condition = condition;
    }
 
    @Override
    public springfox.documentation.spring.wrapper.PatternsRequestCondition combine(
            springfox.documentation.spring.wrapper.PatternsRequestCondition other) {
        if (other instanceof WebMvcPatternsRequestConditionWrapper && !this.equals(other)) {
            return new WebMvcPatternsRequestConditionWrapper(
                    contextPath,
                    condition.combine(((WebMvcPatternsRequestConditionWrapper) other).condition));
        }
        return this;
    }
 
    @Override
    public Set getPatterns() {
        return this.condition.getPatternValues().stream()
                .map(p -> String.format("%s/%s", maybeChompTrailingSlash(contextPath),
                        maybeChompLeadingSlash(p)))
                .collect(Collectors.toSet());
    }
 
 
    @Override
    public boolean equals(Object o) {
        if (o instanceof WebMvcPatternsRequestConditionWrapper) {
            return this.condition.equals(((WebMvcPatternsRequestConditionWrapper) o).condition);
        }
        return false;
    }
 
    @Override
    public int hashCode() {
        return this.condition.hashCode();
    }
 
 
    @Override
    public String toString() {
        return this.condition.toString();
    }
}


 
 

package springfox.documentation.spring.web;
 
import static java.util.Optional.ofNullable;
 
import com.fasterxml.classmate.ResolvedType;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import springfox.documentation.RequestHandler;
import springfox.documentation.RequestHandlerKey;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spring.web.readers.operation.HandlerMethodResolver;
import springfox.documentation.spring.wrapper.NameValueExpression;
import springfox.documentation.spring.wrapper.PatternsRequestCondition;
 
/**
 * swagger3.0兼容springBoot2.6.3处理
 */
public class WebMvcRequestHandler implements RequestHandler {
 
    private final String contextPath;
    private final HandlerMethodResolver methodResolver;
    private final RequestMappingInfo requestMapping;
    private final HandlerMethod handlerMethod;
 
    public WebMvcRequestHandler(
            String contextPath,
            HandlerMethodResolver methodResolver,
            RequestMappingInfo requestMapping,
            HandlerMethod handlerMethod) {
        this.contextPath = contextPath;
        this.methodResolver = methodResolver;
        this.requestMapping = requestMapping;
        this.handlerMethod = handlerMethod;
    }
 
    @Override
    public HandlerMethod getHandlerMethod() {
        return handlerMethod;
    }
 
    @Override
    public RequestHandler combine(RequestHandler other) {
        return this;
    }
 
    @Override
    public Class declaringClass() {
        return handlerMethod.getBeanType();
    }
 
    @Override
    public boolean isAnnotatedWith(Class annotation) {
        return null != AnnotationUtils.findAnnotation(handlerMethod.getMethod(), annotation);
    }
 
    @Override
    public PatternsRequestCondition getPatternsCondition() {
        return new WebMvcPatternsRequestConditionWrapper(
                contextPath,
                requestMapping.getPathPatternsCondition());
    }
 
    @Override
    public String groupName() {
        return ControllerNamingUtils.controllerNameAsGroup(handlerMethod);
    }
 
    @Override
    public String getName() {
        return handlerMethod.getMethod().getName();
    }
 
    @Override
    public Set supportedMethods() {
        return requestMapping.getMethodsCondition().getMethods();
    }
 
    @Override
    public Set produces() {
        return requestMapping.getProducesCondition().getProducibleMediaTypes();
    }
 
    @Override
    public Set consumes() {
        return requestMapping.getConsumesCondition().getConsumableMediaTypes();
    }
 
    @Override
    public Set> headers() {
        return WebMvcNameValueExpressionWrapper
                .from(requestMapping.getHeadersCondition().getExpressions());
    }
 
    @Override
    public Set> params() {
        return WebMvcNameValueExpressionWrapper
                .from(requestMapping.getParamsCondition().getExpressions());
    }
 
    @Override
    public  Optional findAnnotation(Class annotation) {
        return ofNullable(AnnotationUtils.findAnnotation(handlerMethod.getMethod(), annotation));
    }
 
    @Override
    public RequestHandlerKey key() {
        return new RequestHandlerKey(
                requestMapping.getPathPatternsCondition().getPatternValues(),
                requestMapping.getMethodsCondition().getMethods(),
                requestMapping.getConsumesCondition().getConsumableMediaTypes(),
                requestMapping.getProducesCondition().getProducibleMediaTypes());
    }
 
    @Override
    public springfox.documentation.spring.wrapper.RequestMappingInfo getRequestMapping() {
        return new WebMvcRequestMappingInfoWrapper(requestMapping);
    }
 
    @Override
    public List getParameters() {
        return methodResolver.methodParameters(handlerMethod);
    }
 
    @Override
    public ResolvedType getReturnType() {
        return methodResolver.methodReturnType(handlerMethod);
    }
 
    @Override
    public  Optional findControllerAnnotation(Class annotation) {
        return ofNullable(AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), annotation));
    }
 
    @Override
    public String toString() {
        return new StringJoiner(", ", WebMvcRequestHandler.class.getSimpleName() + "{", "}")
                .add("requestMapping=" + requestMapping)
                .add("handlerMethod=" + handlerMethod)
                .add("key=" + key())
                .toString();
    }
}

swagger 配置类添加 bean


import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Value("${swagger.show}")
    private boolean swaggerShow;

    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(swaggerShow)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("xxxxxx")
                .description("xxxxxx")
                .termsOfServiceUrl("")
                .version("1.0")
                .build();
    }

    @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  void customizeSpringfoxHandlerMappings(
                    List mappings) {
                List copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null)
                        .collect(Collectors.toList());
                mappings.clear();
                mappings.addAll(copy);
            }

            @SuppressWarnings("unchecked")
            private List getHandlerMappings(Object bean) {
                try {
                    Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");
                    field.setAccessible(true);
                    return (List) field.get(bean);
                }
                catch (IllegalArgumentException | IllegalAccessException e) {
                    throw new IllegalStateException(e);
                }
            }
        };
    }
}



访问地址 

http://ip:port/swagger/

你可能感兴趣的:(JAVA,spring-boot,java,spring,boot,spring,swagger2)