1、在talent-common引入pom.xml依赖 <!--knife4j--> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-micro-spring-boot-starter</artifactId> <version>2.0.8</version> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>2.0.8</version> </dependency>
2、配置swagger依赖(@EnableSwagger2WebMvc)
<!-- Swagger 依赖配置 -->
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.10.5</version> </dependency>
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> <optional>true</optional> </dependency>
3、添加配置类
package com.purchase.common.config; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.PropertySource; import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.*; 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; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; @EnableKnife4j @EnableSwagger2WebMvc @Configuration @EnableAutoConfiguration @Import(BeanValidatorPluginsConfiguration.class) @ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true) @PropertySource(factory = YamlPropertySourceFactory.class, value = "classpath:wfm-swagger.yml") class SwaggerAutoConfiguration { /** * 默认的排除路径,排除Spring Boot默认的错误处理路径和端点 */ private static final List<String> DEFAULT_EXCLUDE_PATH = Arrays.asList("/error", "/actuator/**"); private static final String BASE_PATH = "/**"; @Bean @ConditionalOnMissingBean public SwaggerProperties swaggerProperties() { return new SwaggerProperties(); } @Bean public Docket api(SwaggerProperties swaggerProperties) { // base-path处理 if (swaggerProperties.getBasePath().isEmpty()) { swaggerProperties.getBasePath().add(BASE_PATH); } // noinspection unchecked List<Predicate<String>> basePath = new ArrayList<Predicate<String>>(); swaggerProperties.getBasePath().forEach(path -> basePath.add(PathSelectors.ant(path))); // exclude-path处理 if (swaggerProperties.getExcludePath().isEmpty()) { swaggerProperties.getExcludePath().addAll(DEFAULT_EXCLUDE_PATH); } List<Predicate<String>> excludePath = new ArrayList<>(); swaggerProperties.getExcludePath().forEach(path -> excludePath.add(PathSelectors.ant(path))); //noinspection Guava return new Docket(DocumentationType.SWAGGER_2) .host(swaggerProperties.getHost()) .apiInfo(apiInfo(swaggerProperties)).select() .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())) // .paths(Predicates.and(Predicates.not(Predicates.or(excludePath)), Predicates.or(basePath))) .paths(PathSelectors.any()) .build() .securitySchemes(securitySchemes()) .securityContexts(securityContexts()) .pathMapping("/"); } /** * 安全模式,这里指定token通过Authorization头请求头传递 */ private List<ApiKey> securitySchemes() { List<ApiKey> apiKeyList = new ArrayList<ApiKey>(); apiKeyList.add(new ApiKey("Authorization", "Authorization", "header")); return apiKeyList; } /** * 安全上下文 */ private List<SecurityContext> securityContexts() { List<SecurityContext> securityContexts = new ArrayList<>(); securityContexts.add( SecurityContext.builder() .securityReferences(defaultAuth()) .forPaths(PathSelectors.regex("^(?!auth).*$")) .build()); return securityContexts; } /** * 默认的全局鉴权策略 * * @return */ private List<SecurityReference> defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; List<SecurityReference> securityReferences = new ArrayList<>(); securityReferences.add(new SecurityReference("Authorization", authorizationScopes)); return securityReferences; } private ApiInfo apiInfo(SwaggerProperties swaggerProperties) { return new ApiInfoBuilder() .title(swaggerProperties.getTitle()) .description(swaggerProperties.getDescription()) .license(swaggerProperties.getLicense()) .licenseUrl(swaggerProperties.getLicenseUrl()) .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl()) .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail())) .version(swaggerProperties.getVersion()) .build(); } }
package com.purchase.common.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; @Component @ConfigurationProperties("swagger") public class SwaggerProperties { /** * 是否开启swagger */ private Boolean enabled; /** * swagger会解析的包路径 **/ private String basePackage = ""; /** * swagger会解析的url规则 **/ private List<String> basePath = new ArrayList<>(); /** * 在basePath基础上需要排除的url规则 **/ private List<String> excludePath = new ArrayList<>(); /** * 标题 **/ private String title = ""; /** * 描述 **/ private String description = ""; /** * 版本 **/ private String version = ""; /** * 许可证 **/ private String license = ""; /** * 许可证URL **/ private String licenseUrl = ""; /** * 服务条款URL **/ private String termsOfServiceUrl = ""; /** * host信息 **/ private String host = ""; /** * 联系人信息 */ private Contact contact = new Contact(); /** * 全局统一鉴权配置 **/ private Authorization authorization = new Authorization(); public Boolean getEnabled() { return enabled; } public void setEnabled(Boolean enabled) { this.enabled = enabled; } public String getBasePackage() { return basePackage; } public void setBasePackage(String basePackage) { this.basePackage = basePackage; } public List<String> getBasePath() { return basePath; } public void setBasePath(List<String> basePath) { this.basePath = basePath; } public List<String> getExcludePath() { return excludePath; } public void setExcludePath(List<String> excludePath) { this.excludePath = excludePath; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } public String getLicense() { return license; } public void setLicense(String license) { this.license = license; } public String getLicenseUrl() { return licenseUrl; } public void setLicenseUrl(String licenseUrl) { this.licenseUrl = licenseUrl; } public String getTermsOfServiceUrl() { return termsOfServiceUrl; } public void setTermsOfServiceUrl(String termsOfServiceUrl) { this.termsOfServiceUrl = termsOfServiceUrl; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public Contact getContact() { return contact; } public void setContact(Contact contact) { this.contact = contact; } public Authorization getAuthorization() { return authorization; } public void setAuthorization(Authorization authorization) { this.authorization = authorization; } public static class Contact { /** * 联系人 **/ private String name = ""; /** * 联系人url **/ private String url = ""; /** * 联系人email **/ private String email = ""; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } public static class Authorization { /** * 鉴权策略ID,需要和SecurityReferences ID保持一致 */ private String name = ""; /** * 需要开启鉴权URL的正则 */ private String authRegex = "^.*$"; /** * 鉴权作用域列表 */ private List<AuthorizationScope> authorizationScopeList = new ArrayList<>(); private List<String> tokenUrlList = new ArrayList<>(); public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthRegex() { return authRegex; } public void setAuthRegex(String authRegex) { this.authRegex = authRegex; } public List<AuthorizationScope> getAuthorizationScopeList() { return authorizationScopeList; } public void setAuthorizationScopeList(List<AuthorizationScope> authorizationScopeList) { this.authorizationScopeList = authorizationScopeList; } public List<String> getTokenUrlList() { return tokenUrlList; } public void setTokenUrlList(List<String> tokenUrlList) { this.tokenUrlList = tokenUrlList; } } public static class AuthorizationScope { /** * 作用域名称 */ private String scope = ""; /** * 作用域描述 */ private String description = ""; public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } }
package com.purchase.common.config; import lombok.AllArgsConstructor; import org.springframework.beans.factory.config.YamlPropertiesFactoryBean; import org.springframework.core.env.PropertiesPropertySource; import org.springframework.core.env.PropertySource; import org.springframework.core.io.support.EncodedResource; import org.springframework.core.io.support.PropertySourceFactory; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; /** * @Author */ @AllArgsConstructor public class YamlPropertySourceFactory implements PropertySourceFactory { public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException { Properties propertiesFromYaml = loadYamlIntoProperties(resource); String sourceName = name != null ? name : resource.getResource().getFilename(); assert sourceName != null; return new PropertiesPropertySource(sourceName, propertiesFromYaml); } private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException { try { YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean(); factory.setResources(resource.getResource()); factory.afterPropertiesSet(); return factory.getObject(); } catch (IllegalStateException e) { Throwable cause = e.getCause(); if (cause instanceof FileNotFoundException) { throw (FileNotFoundException) e.getCause(); } throw e; } } }
报错
解决:springboot版本和knife4j的版本不适配
报错
Caused by: java.lang.NoSuchMethodError: org.springframework.plugin.core.PluginRegistry.getPluginOrDefaultFor(Ljava/lang/Object;Lorg/springframework/plugin/core/Plugin;)Lorg/springframework/plugin/core/Plugin;
解决:springboot版本和knife4j的版本不适配(springboot原版本1.5.2,knife4j原版本2.0.8修改为2.0.4)