package com.cnbm.config; import com.cnbm.common.constant.Constant; import com.google.common.collect.Lists; import io.swagger.annotations.ApiOperation; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.util.ReflectionUtils; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.oas.annotations.EnableOpenApi; 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.spring.web.plugins.WebFluxRequestHandlerProvider; import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; import java.lang.reflect.Field; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import static com.google.common.collect.Lists.newArrayList; /** * @Author weihongyang * @Date 2022/6/21 10:56 AM * @Version 1.0 */ @Configuration @EnableOpenApi @Profile("dev") @EnableWebMvc public class SwaggerConfig { /** * 创建API应用 * apiInfo() 增加API相关信息 * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现, * 本例采用指定扫描的包路径来定义指定要建立API的目录。 * * @return */ @Bean public Docket restApi() { return new Docket(DocumentationType.SWAGGER_2) .groupName("全部接口") .apiInfo(apiInfo("Spring Boot中使用Swagger2构建RESTful APIs", "1.0")) .useDefaultResponseMessages(true) .forCodeGeneration(false) .select() .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) .paths(PathSelectors.any()) .build() .securityContexts(Arrays.asList(securityContext())) // ApiKey的name需与SecurityReference的reference保持一致 .securitySchemes(Arrays.asList(new ApiKey("token", "token", "header"))); } @Bean public Docket adminApi() { return new Docket(DocumentationType.SWAGGER_2) .groupName("admin模块接口") .apiInfo(apiInfo("Spring Boot中使用Swagger2构建RESTful APIs", "1.0")) .useDefaultResponseMessages(true) .forCodeGeneration(false) .select() .apis(RequestHandlerSelectors.basePackage("com.cnbm.admin")) .paths(PathSelectors.any()) .build() .securityContexts(Arrays.asList(securityContext())) // ApiKey的name需与SecurityReference的reference保持一致 .securitySchemes(Arrays.asList(new ApiKey("token", "token", "header"))); } @Bean public Docket basicApi() { return new Docket(DocumentationType.SWAGGER_2) .groupName("ym-basic") .apiInfo(apiInfos("basic", "基础资料模块")) .useDefaultResponseMessages(true) .forCodeGeneration(false) .select() .apis(RequestHandlerSelectors.basePackage("com.cnbm.basic")) .paths(PathSelectors.any()) .build() .securityContexts(Arrays.asList(securityContext())) // ApiKey的name需与SecurityReference的reference保持一致 .securitySchemes(Arrays.asList(new ApiKey("token", "token", "header"))); } @Bean public Docket influxApi() { return new Docket(DocumentationType.SWAGGER_2) .groupName("ym-influx") .apiInfo(apiInfos("influx", "influx模块")) .useDefaultResponseMessages(true) .forCodeGeneration(false) .select() .apis(RequestHandlerSelectors.basePackage("com.cnbm.influx")) .paths(PathSelectors.any()) .build() .securityContexts(Arrays.asList(securityContext())) // ApiKey的name需与SecurityReference的reference保持一致 .securitySchemes(Arrays.asList(new ApiKey("token", "token", "header"))); } /** * 创建该API的基本信息(这些基本信息会展现在文档页面中) * 访问地址:http://ip:port/swagger-ui.html * * @return */ private ApiInfo apiInfo(String title, String version) { return new ApiInfoBuilder() .title(title) .description("ym-pass文档") .termsOfServiceUrl("https://www.baidu.com/") .version(version) .build(); } private ApiInfo apiInfos(String title, String desc) { return new ApiInfoBuilder() .title(title) .description(desc) .termsOfServiceUrl("https://www.baidu.com/") .version("1.0") .build(); } private SecurityContext securityContext() { return SecurityContext.builder() .securityReferences(defaultAuth()) .build(); } List defaultAuth() { AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; authorizationScopes[0] = authorizationScope; return Lists.newArrayList( new SecurityReference(Constant.TOKEN_HEADER, authorizationScopes)); } @Bean public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() { return new BeanPostProcessor() { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); } return bean; } private void customizeSpringfoxHandlerMappings(List mappings) { List copy = mappings.stream() .filter(mapping -> mapping.getPatternParser() == null) .collect(Collectors.toList()); mappings.clear(); mappings.addAll(copy); } @SuppressWarnings("unchecked") private List getHandlerMappings(Object bean) { try { Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); field.setAccessible(true); return (List) field.get(bean); } catch (IllegalArgumentException | IllegalAccessException e) { throw new IllegalStateException(e); } } }; } }