package com.hollywood.common.swagger;
|
|
import io.swagger.annotations.ApiOperation;
|
import org.apache.commons.lang3.reflect.FieldUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Profile;
|
import org.springframework.http.HttpMethod;
|
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import springfox.documentation.builders.*;
|
import springfox.documentation.oas.annotations.EnableOpenApi;
|
import springfox.documentation.service.*;
|
import springfox.documentation.spi.DocumentationType;
|
import springfox.documentation.spring.web.plugins.Docket;
|
|
import java.lang.reflect.Field;
|
import java.util.*;
|
|
/**
|
* swagger3 的spring-boot启动器
|
*
|
* @author ck
|
*/
|
@Configuration
|
@ConditionalOnProperty(name = "web.swagger.enabled")
|
@EnableConfigurationProperties(SwaggerProperties.class)
|
@EnableOpenApi
|
@ConditionalOnClass(Docket.class)
|
@Profile({"dev", "test","prod"})
|
public class SwaggerAutoConfiguration implements WebMvcConfigurer {
|
|
private final SwaggerProperties swaggerProperties;
|
|
@Autowired
|
public SwaggerAutoConfiguration(SwaggerProperties swaggerProperties) {
|
this.swaggerProperties = swaggerProperties;
|
}
|
|
/**
|
* 文档相关资源路径
|
*/
|
public static final String[] DOC_LIST =
|
{"/js/**",
|
"/css/**",
|
"/static/**",
|
"/webass/**",
|
"/iconfont/**",
|
"/RFIDR/**",
|
"/tinymce/**",
|
"/img/**",
|
"/images/**",
|
"/fonts/**","/index.html",
|
"/favicon.ico", "/v3/**", "/v2/**",
|
"/error", "/swagger**/**", "/configuration/ui",
|
"/configuration/security", "/webjars/**", "/doc**/**"
|
,"/swagger-resources/**", "/swagger-ui.html/**"
|
};
|
|
/**
|
* 支持的通讯协议集合
|
*
|
* @return
|
*/
|
private Set<String> protocols() {
|
Set<String> set = new HashSet<>();
|
set.add("https");
|
set.add("http");
|
return set;
|
}
|
|
/**
|
* 响应状态集合
|
*
|
* @return
|
*/
|
private List<Response> responseList() {
|
List<Response> responseList = new ArrayList<>();
|
Arrays.stream(GlobalResultEnum.values()).forEach(errorEnum -> {
|
responseList.add(
|
new ResponseBuilder().code(String.valueOf(errorEnum.getCode())).description(errorEnum.getMessage()).build()
|
);
|
});
|
return responseList;
|
}
|
|
/**
|
* 设置文档基本信息
|
*
|
* @return
|
*/
|
private ApiInfo apiInfo(SwaggerProperties.Contact contact) {
|
SwaggerProperties.Contact cont = Objects.isNull(contact) ? swaggerProperties.getContact() : contact;
|
return new ApiInfoBuilder()
|
.title(swaggerProperties.getTitle())
|
.description(swaggerProperties.getDescription())
|
.termsOfServiceUrl(swaggerProperties.getServiceUrl())
|
.contact(new Contact(cont.getName(), cont.getUrl(), cont.getEmail()))
|
.version(swaggerProperties.getVersion())
|
.license(swaggerProperties.getLicense())
|
.licenseUrl(swaggerProperties.getLicenseUrl())
|
.build();
|
}
|
|
/**
|
* 生成全局头部通用参数
|
*
|
* @return
|
*/
|
private List<RequestParameter> setFixedParameter(List<SwaggerProperties.ReqFixedParameter> reqFixedParameters) {
|
List<RequestParameter> parameters = new ArrayList<>();
|
List<SwaggerProperties.ReqFixedParameter> fixedParameters = CollectionUtils.isEmpty(reqFixedParameters) ? swaggerProperties.getReqFixedParameters() : reqFixedParameters;
|
for (SwaggerProperties.ReqFixedParameter reqFixedParameter : fixedParameters) {
|
parameters.add(new RequestParameterBuilder()
|
.name(reqFixedParameter.getParamKey())
|
.description(reqFixedParameter.getDescription())
|
.required(reqFixedParameter.isRequired())
|
.in(ParameterType.HEADER)
|
.build());
|
}
|
return parameters;
|
}
|
|
/**
|
* 默认分组
|
*
|
* @return
|
*/
|
@Bean
|
@ConditionalOnMissingBean
|
public Docket docket() {
|
return new Docket(DocumentationType.OAS_30)
|
.enable(swaggerProperties.isEnabled())
|
.groupName("全部")
|
.globalResponses(HttpMethod.GET, responseList())
|
.globalResponses(HttpMethod.POST, responseList())
|
.globalResponses(HttpMethod.PUT, responseList())
|
.globalResponses(HttpMethod.DELETE, responseList())
|
.apiInfo(apiInfo(swaggerProperties.getContact()))
|
.select()
|
// 表示任何包
|
// 加了ApiOperation注解的类,才生成接口文档
|
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
.paths(PathSelectors.any())
|
// 避免使用swagger api的默认basic-error-controller
|
// .paths(PathSelectors.regex("(?!/error.*).*"))
|
.build()
|
// .securitySchemes(securitySchemes())
|
// 支持的通讯协议集合
|
.protocols(protocols())
|
//.securityContexts(securityContexts())
|
.pathMapping(swaggerProperties.getPathMapping())
|
.globalRequestParameters(setFixedParameter(swaggerProperties.getReqFixedParameters()));
|
}
|
|
|
/**
|
* 接口请求拦截配置
|
*
|
* @param registry
|
*/
|
@Override
|
public void addViewControllers(ViewControllerRegistry registry) {
|
registry.addRedirectViewController("/swagger", "/swagger-ui/index.html");
|
}
|
|
/**
|
* 通用拦截器排除swagger设置,所有拦截器都会自动加swagger相关的资源排除信息
|
*/
|
@Override
|
public void addInterceptors(InterceptorRegistry registry) {
|
Field registrationsField = FieldUtils.getField(InterceptorRegistry.class, "registrations", true);
|
List<InterceptorRegistration> registrations = (List<InterceptorRegistration>) ReflectionUtils.getField(registrationsField, registry);
|
if (!CollectionUtils.isEmpty(registrations)) {
|
for (InterceptorRegistration interceptorRegistration : registrations) {
|
interceptorRegistration
|
.excludePathPatterns(DOC_LIST);
|
}
|
}
|
}
|
}
|