package com.artfess.base.conf; import com.artfess.base.annotation.ApiGroup; import com.google.common.base.Optional; import com.google.common.base.Predicate; import com.google.common.collect.Lists; import org.springframework.beans.factory.annotation.Value; import org.springframework.format.FormatterRegistry; import org.springframework.util.StringUtils; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import springfox.documentation.RequestHandler; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.ApiKey; import springfox.documentation.service.AuthorizationScope; import springfox.documentation.service.Contact; import springfox.documentation.service.SecurityReference; import springfox.documentation.service.VendorExtension; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.ApiSelectorBuilder; import springfox.documentation.spring.web.plugins.Docket; import org.springframework.core.convert.converter.Converter; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Swagger配置辅助方法基础类 * @author mikel */ public abstract class SwaggerConfigHelper implements WebMvcConfigurer { @Value("${spring.profiles.title}") private String title; @Value("${spring.profiles.description}") private String description; @Value("${spring.profiles.version}") private String version; @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(localDateConvert()); } public Converter localDateConvert() { // 不能替换为lambda表达式 return new Converter() { @Override public LocalDate convert(String source) { if (StringUtils.hasText(source)) { return LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd")); } return null; } }; } /** * 根据分组构建完整的API注册信息 * @param apiGroupName * @param apiGroupKey * @return */ public Docket buildProductApi(String apiGroupName, String apiGroupKey) { Docket docket = buildDocket(apiGroupName).apiInfo(buildBaseProductApiInfo()); ApiSelectorBuilder builder = buildApiForGroupKey(docket, apiGroupKey); return buildApiSecurityAuth(builder); } /** * 根据分组名创建Docket * @param apiGroupName * @return */ public Docket buildDocket(String apiGroupName) { return new Docket(DocumentationType.SWAGGER_2) .groupName(apiGroupName) //.apiInfo(buildBaseProductApiInfo(title, description, version)) .useDefaultResponseMessages(false) .forCodeGeneration(false); } /** * 根据分组key对API进行注册 * @param docket * @param apiGroupKey * @return */ public ApiSelectorBuilder buildApiForGroupKey(Docket docket, String apiGroupKey) { return docket.select() .apis(getPredicateWithGroup(apiGroupKey)) .paths(PathSelectors.any()); } /** * 根据基础包名对API进行注册 * @param docket * @param basePackage * @return */ public ApiSelectorBuilder buildApiForPackage(Docket docket, String basePackage) { return docket.select() .apis(RequestHandlerSelectors.basePackage(basePackage)) .paths(PathSelectors.any()); } /** * 构建API安全认证 * @param builder * @return */ public Docket buildApiSecurityAuth(ApiSelectorBuilder builder) { return builder.build().securityContexts(Lists.newArrayList(buildSecurityContext())) .securitySchemes(Lists.newArrayList(apiSecurityKey())); } private ApiKey apiSecurityKey() { return new ApiKey("BearerToken", "Authorization", "header"); } private SecurityContext buildSecurityContext() { return SecurityContext.builder() .securityReferences(defaultAuth()) .forPaths(PathSelectors.regex("/.*")) .build(); } /** * 默认的认证方式 * @return */ private List defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; return Lists.newArrayList(new SecurityReference("BearerToken", authorizationScopes)); } /** * 通过接口分组过滤 * @param group * @return */ protected Predicate getPredicateWithGroup(String group) { return new Predicate() { @Override public boolean apply(RequestHandler input) { // 找到controller类上的ApiGroup注解 Optional ApiGroup = input.findControllerAnnotation(ApiGroup.class); if(ApiGroup.isPresent() && Arrays.asList(ApiGroup.get().group()).contains(group)) { return true; } return false; } }; } protected ApiInfo buildBaseProductApiInfo() { Contact contact = new Contact("liangyan", "www.Artfess.com", "liangyan@artfess.com"); return buildApiInfo(title, description, version, "http://127.0.0.1:8080", contact); } @SuppressWarnings("rawtypes") protected ApiInfo buildApiInfo(String title, String description, String version, String url, Contact contact) { ApiInfo apiInfo = new ApiInfo(title, description, version, url, contact, "license", "license url", new ArrayList()); return apiInfo; } /** * * 显示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/"); } }