*************************** APPLICATION FAILED TO START *************************** Description: An attempt was made to call a method that does not exist. The attempt was made from the following location: com.be.common.web.configurer.SwaggerConfigurer.docket(SwaggerConfigurer.java:51) The following method did not exist: springfox.documentation.builders.RequestHandlerSelectors.basePackage(Ljava/lang/String;)Lcom/google/common/base/Predicate; The method's class, springfox.documentation.builders.RequestHandlerSelectors, is available from the following locations: jar:file:/Users/u/.m2/repository/io/springfox/springfox-core/3.0.0/springfox-core-3.0.0.jar!/springfox/documentation/builders/RequestHandlerSelectors.class It was loaded from the following location: file:/Users/u/.m2/repository/io/springfox/springfox-core/3.0.0/springfox-core-3.0.0.jar Action: Correct the classpath of your application so that it contains a single, compatible version of springfox.documentation.builders.RequestHandlerSelectors
原因是可能重复配置swagger,可能是其他框架配置swagger了,只需要把框架内置的swagger配置禁用。
然后手动配置下knife4j 就可以了
package com.x.serving.core.config; import com.x.serving.annotation.SwaggerApi; import com.x.serving.common.constants.ServingConstants; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; import io.swagger.annotations.ApiOperation; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ParameterBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.schema.ModelRef; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.ApiKey; import springfox.documentation.service.AuthorizationScope; import springfox.documentation.service.Contact; import springfox.documentation.service.Parameter; import springfox.documentation.service.SecurityReference; import springfox.documentation.service.SecurityScheme; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc; /** * @author x * @version 1.0.0 * @email <a href="x.x@x.cn">muzhi</a> * @date 2022-02-14 15:19 */ @Configuration @EnableSwagger2WebMvc @EnableKnife4j @Import(BeanValidatorPluginsConfiguration.class) public class Swagger2Configuration implements WebMvcConfigurer { @Override public void addViewControllers(final ViewControllerRegistry registry) { registry.addViewController("/").setViewName("doc.html"); } /** * * 显示swagger-ui.html文档展示页,还必须注入swagger资源: * * @param registry */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); } /** * swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等 * * @return Docket */ @Bean(value = "defaultApi2") public Docket defaultApi2() { // List<ResponseMessage> responseMessages = new ArrayList<>(2); // ResponseMessage build = new ResponseMessageBuilder().code(200) // .message("").responseModel(new ModelRef(Response.class.getName())) // .build(); // // responseMessages.add(build); return new Docket(DocumentationType.SWAGGER_2) // .globalResponseMessage(RequestMethod.GET, responseMessages) // .globalResponseMessage(RequestMethod.POST, responseMessages) .apiInfo(apiInfo()) .select() //此包路径下的类,才生成接口文档 .apis(RequestHandlerSelectors.basePackage("com.be.edge.serving") .or(RequestHandlerSelectors.withClassAnnotation(SwaggerApi.class))) //加了ApiOperation注解的类,才生成接口文档 .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .paths(PathSelectors.any()) .build() .securitySchemes(Collections.singletonList(securityScheme())) .securityContexts(securityContexts()); //.globalOperationParameters(setHeaderToken()); } /*** * oauth2配置 * 需要增加swagger授权回调地址 * http://localhost:8888/webjars/springfox-swagger-ui/o2c.html * @return */ @Bean SecurityScheme securityScheme() { return new ApiKey(ServingConstants.TOKEN_NAME, ServingConstants.TOKEN_NAME, "header"); } /** * JWT token * @return */ private List<Parameter> setHeaderToken() { ParameterBuilder tokenPar = new ParameterBuilder(); List<Parameter> pars = new ArrayList<>(); tokenPar.name(ServingConstants.TOKEN_NAME).description(ServingConstants.TOKEN_DESCRIPTION).modelRef(new ModelRef("string")).parameterType("header").required(false).build(); pars.add(tokenPar.build()); return pars; } /** * api文档的详细信息函数,注意这里的注解引用的是哪个 * * @return */ private ApiInfo apiInfo() { return new ApiInfoBuilder() // //大标题 .title("EdgeX-Lambda 后台服务API接口文档") // 版本号 .version("1.0") // .termsOfServiceUrl("NO terms of service") // 描述 .description("后台API接口") // 作者 .contact(new Contact("牧之", "http://localhost:6500/", "email@mail.com")) .license("The Apache License, Version 2.0") .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") .build(); } /** * 新增 securityContexts 保持登录状态 */ private List<SecurityContext> securityContexts() { return new ArrayList( Collections.singleton(SecurityContext.builder() .securityReferences(defaultAuth()) .forPaths(PathSelectors.regex("^(?!auth).*$")) .build()) ); } private List<SecurityReference> defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; return new ArrayList( Collections.singleton(new SecurityReference(ServingConstants.TOKEN_NAME, authorizationScopes))); } }
#swagger
knife4j:
#开启增强配置
enable: true
#开启生产环境屏蔽
production: false