package com.kidgrow.swagger2;
|
|
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicates;
|
import com.google.common.collect.Lists;
|
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactoryAware;
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
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.Import;
|
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.spi.DocumentationType;
|
import springfox.documentation.spi.service.contexts.SecurityContext;
|
import springfox.documentation.spring.web.plugins.Docket;
|
|
import java.util.ArrayList;
|
import java.util.LinkedList;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.Set;
|
import java.util.stream.Collectors;
|
|
/**
|
* 石家庄喜高科技有限责任公司 版权所有 © Copyright 2020<br>
|
*
|
* @Description: <br>
|
* @Project: <br>
|
* @CreateDate: Created in 2020/2/4 16:05 <br>
|
* @Author: <a href="4345453@kidgrow.com">liuke</a>
|
*/
|
@Import( {
|
Swagger2Configuration.class
|
})
|
public class SwaggerAutoConfiguration implements BeanFactoryAware {
|
private static final String AUTH_KEY = "Authorization";
|
|
private BeanFactory beanFactory;
|
|
@Bean
|
@ConditionalOnMissingBean
|
public SwaggerProperties swaggerProperties() {
|
return new SwaggerProperties();
|
}
|
|
@Bean
|
@ConditionalOnMissingBean
|
@ConditionalOnProperty(name = "kidgrow.swagger.enabled", matchIfMissing = true)
|
public List<Docket> createRestApi(SwaggerProperties swaggerProperties) {
|
ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory;
|
List<Docket> docketList = new LinkedList<>();
|
|
// 没有分组
|
if (swaggerProperties.getDocket().size() == 0) {
|
final Docket docket = createDocket(swaggerProperties);
|
configurableBeanFactory.registerSingleton("defaultDocket", docket);
|
docketList.add(docket);
|
return docketList;
|
}
|
|
// 分组创建
|
for (String groupName : swaggerProperties.getDocket().keySet()) {
|
SwaggerProperties.DocketInfo docketInfo = swaggerProperties.getDocket().get(groupName);
|
|
ApiInfo apiInfo = new ApiInfoBuilder()
|
.title(docketInfo.getTitle().isEmpty() ? swaggerProperties.getTitle() : docketInfo.getTitle())
|
.description(docketInfo.getDescription().isEmpty() ? swaggerProperties.getDescription() : docketInfo.getDescription())
|
.version(docketInfo.getVersion().isEmpty() ? swaggerProperties.getVersion() : docketInfo.getVersion())
|
.license(docketInfo.getLicense().isEmpty() ? swaggerProperties.getLicense() : docketInfo.getLicense())
|
.licenseUrl(docketInfo.getLicenseUrl().isEmpty() ? swaggerProperties.getLicenseUrl() : docketInfo.getLicenseUrl())
|
.contact(
|
new Contact(
|
docketInfo.getContact().getName().isEmpty() ? swaggerProperties.getContact().getName() : docketInfo.getContact().getName(),
|
docketInfo.getContact().getUrl().isEmpty() ? swaggerProperties.getContact().getUrl() : docketInfo.getContact().getUrl(),
|
docketInfo.getContact().getEmail().isEmpty() ? swaggerProperties.getContact().getEmail() : docketInfo.getContact().getEmail()
|
)
|
)
|
.termsOfServiceUrl(docketInfo.getTermsOfServiceUrl().isEmpty() ? swaggerProperties.getTermsOfServiceUrl() : docketInfo.getTermsOfServiceUrl())
|
.build();
|
|
// base-path处理
|
// 当没有配置任何path的时候,解析/**
|
if (docketInfo.getBasePath().isEmpty()) {
|
docketInfo.getBasePath().add("/**");
|
}
|
List<Predicate<String>> basePath = new ArrayList<>(docketInfo.getBasePath().size());
|
for (String path : docketInfo.getBasePath()) {
|
basePath.add(PathSelectors.ant(path));
|
}
|
|
// exclude-path处理
|
List<Predicate<String>> excludePath = new ArrayList<>(docketInfo.getExcludePath().size());
|
for (String path : docketInfo.getExcludePath()) {
|
excludePath.add(PathSelectors.ant(path));
|
}
|
|
Docket docket = new Docket(DocumentationType.SWAGGER_2)
|
.host(swaggerProperties.getHost())
|
.apiInfo(apiInfo)
|
.globalOperationParameters(assemblyGlobalOperationParameters(swaggerProperties.getGlobalOperationParameters(),
|
docketInfo.getGlobalOperationParameters()))
|
.groupName(groupName)
|
.select()
|
.apis(RequestHandlerSelectors.basePackage(docketInfo.getBasePackage()))
|
.paths(
|
Predicates.and(
|
Predicates.not(Predicates.or(excludePath)),
|
Predicates.or(basePath)
|
)
|
)
|
.build()
|
.securitySchemes(securitySchemes())
|
.securityContexts(securityContexts());
|
|
configurableBeanFactory.registerSingleton(groupName, docket);
|
docketList.add(docket);
|
}
|
return docketList;
|
}
|
|
/**
|
* 创建 Docket对象
|
*
|
* @param swaggerProperties swagger配置
|
* @return Docket
|
*/
|
private Docket createDocket(final SwaggerProperties swaggerProperties) {
|
ApiInfo apiInfo = new ApiInfoBuilder()
|
.title(swaggerProperties.getTitle())
|
.description(swaggerProperties.getDescription())
|
.version(swaggerProperties.getVersion())
|
.license(swaggerProperties.getLicense())
|
.licenseUrl(swaggerProperties.getLicenseUrl())
|
.contact(new Contact(swaggerProperties.getContact().getName(),
|
swaggerProperties.getContact().getUrl(),
|
swaggerProperties.getContact().getEmail()))
|
.termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
|
.build();
|
|
// base-path处理
|
// 当没有配置任何path的时候,解析/**
|
if (swaggerProperties.getBasePath().isEmpty()) {
|
swaggerProperties.getBasePath().add("/**");
|
}
|
List<Predicate<String>> basePath = new ArrayList<>();
|
for (String path : swaggerProperties.getBasePath()) {
|
basePath.add(PathSelectors.ant(path));
|
}
|
|
// exclude-path处理
|
List<Predicate<String>> excludePath = new ArrayList<>();
|
for (String path : swaggerProperties.getExcludePath()) {
|
excludePath.add(PathSelectors.ant(path));
|
}
|
|
return new Docket(DocumentationType.SWAGGER_2)
|
.host(swaggerProperties.getHost())
|
.apiInfo(apiInfo)
|
.globalOperationParameters(buildGlobalOperationParametersFromSwaggerProperties(
|
swaggerProperties.getGlobalOperationParameters()))
|
.select()
|
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
|
.paths(
|
Predicates.and(
|
Predicates.not(Predicates.or(excludePath)),
|
Predicates.or(basePath)
|
)
|
)
|
.build()
|
.securitySchemes(securitySchemes())
|
.securityContexts(securityContexts());
|
}
|
|
@Override
|
public void setBeanFactory(BeanFactory beanFactory) {
|
this.beanFactory = beanFactory;
|
}
|
|
private List<SecurityContext> securityContexts() {
|
List<SecurityContext> contexts = new ArrayList<>(1);
|
SecurityContext securityContext = SecurityContext.builder()
|
.securityReferences(defaultAuth())
|
//.forPaths(PathSelectors.regex("^(?!auth).*$"))
|
.build();
|
contexts.add(securityContext);
|
return contexts;
|
}
|
|
private List<SecurityReference> defaultAuth() {
|
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
|
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
authorizationScopes[0] = authorizationScope;
|
List<SecurityReference> references = new ArrayList<>(1);
|
references.add(new SecurityReference(AUTH_KEY, authorizationScopes));
|
return references;
|
}
|
|
private List<ApiKey> securitySchemes() {
|
List<ApiKey> apiKeys = new ArrayList<>(1);
|
ApiKey apiKey = new ApiKey(AUTH_KEY, AUTH_KEY, "header");
|
apiKeys.add(apiKey);
|
return apiKeys;
|
}
|
|
private List<Parameter> buildGlobalOperationParametersFromSwaggerProperties(
|
List<SwaggerProperties.GlobalOperationParameter> globalOperationParameters) {
|
List<Parameter> parameters = Lists.newArrayList();
|
|
if (Objects.isNull(globalOperationParameters)) {
|
return parameters;
|
}
|
for (SwaggerProperties.GlobalOperationParameter globalOperationParameter : globalOperationParameters) {
|
parameters.add(new ParameterBuilder()
|
.name(globalOperationParameter.getName())
|
.description(globalOperationParameter.getDescription())
|
.modelRef(new ModelRef(globalOperationParameter.getModelRef()))
|
.parameterType(globalOperationParameter.getParameterType())
|
.required(Boolean.parseBoolean(globalOperationParameter.getRequired()))
|
.build());
|
}
|
return parameters;
|
}
|
|
/**
|
* 局部参数按照name覆盖局部参数
|
*
|
* @param globalOperationParameters
|
* @param docketOperationParameters
|
* @return
|
*/
|
private List<Parameter> assemblyGlobalOperationParameters(
|
List<SwaggerProperties.GlobalOperationParameter> globalOperationParameters,
|
List<SwaggerProperties.GlobalOperationParameter> docketOperationParameters) {
|
|
if (Objects.isNull(docketOperationParameters) || docketOperationParameters.isEmpty()) {
|
return buildGlobalOperationParametersFromSwaggerProperties(globalOperationParameters);
|
}
|
|
Set<String> docketNames = docketOperationParameters.stream()
|
.map(SwaggerProperties.GlobalOperationParameter::getName)
|
.collect(Collectors.toSet());
|
|
List<SwaggerProperties.GlobalOperationParameter> resultOperationParameters = Lists.newArrayList();
|
|
if (Objects.nonNull(globalOperationParameters)) {
|
for (SwaggerProperties.GlobalOperationParameter parameter : globalOperationParameters) {
|
if (!docketNames.contains(parameter.getName())) {
|
resultOperationParameters.add(parameter);
|
}
|
}
|
}
|
|
resultOperationParameters.addAll(docketOperationParameters);
|
return buildGlobalOperationParametersFromSwaggerProperties(resultOperationParameters);
|
}
|
}
|