You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
8.2 KiB
205 lines
8.2 KiB
package cc.niushuai.bastionserver.config; |
|
|
|
|
|
import cc.niushuai.bastionserver.common.constant.CommonConstant; |
|
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; |
|
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.Import; |
|
import org.springframework.util.ReflectionUtils; |
|
import org.springframework.web.bind.annotation.RestController; |
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; |
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
|
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; |
|
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; |
|
import springfox.documentation.builders.ApiInfoBuilder; |
|
import springfox.documentation.builders.PathSelectors; |
|
import springfox.documentation.builders.RequestHandlerSelectors; |
|
import springfox.documentation.builders.RequestParameterBuilder; |
|
import springfox.documentation.schema.ScalarType; |
|
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 springfox.documentation.swagger2.annotations.EnableSwagger2; |
|
|
|
import java.lang.reflect.Field; |
|
import java.util.ArrayList; |
|
import java.util.Collections; |
|
import java.util.List; |
|
import java.util.stream.Collectors; |
|
|
|
/** |
|
* swagger 配置类 |
|
* |
|
* @author |
|
*/ |
|
@Configuration |
|
@EnableSwagger2 //开启 Swagger2 |
|
@EnableKnife4j //开启 knife4j,可以不写 |
|
@Import(BeanValidatorPluginsConfiguration.class) |
|
public class Swagger2Config implements WebMvcConfigurer { |
|
|
|
/** |
|
* 解决springboot2.6 和springfox不兼容问题 |
|
* |
|
* @return |
|
*/ |
|
@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 <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) { |
|
List<T> copy = mappings.stream() |
|
.filter(mapping -> mapping.getPatternParser() == null) |
|
.collect(Collectors.toList()); |
|
mappings.clear(); |
|
mappings.addAll(copy); |
|
} |
|
|
|
@SuppressWarnings("unchecked") |
|
private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) { |
|
try { |
|
Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); |
|
field.setAccessible(true); |
|
return (List<RequestMappingInfoHandlerMapping>) field.get(bean); |
|
} catch (IllegalArgumentException | IllegalAccessException e) { |
|
throw new IllegalStateException(e); |
|
} |
|
} |
|
}; |
|
} |
|
|
|
/** |
|
* 显示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/"); |
|
} |
|
|
|
/** |
|
* swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等 |
|
* |
|
* @return Docket |
|
*/ |
|
@Bean(value = "defaultApi2") |
|
public Docket defaultApi2() { |
|
return new Docket(DocumentationType.SWAGGER_2) |
|
.apiInfo(apiInfo()) |
|
.select() |
|
//此包路径下的类,才生成接口文档 |
|
.apis(RequestHandlerSelectors.basePackage("cc.niushuai.bastionserver")) |
|
//加了ApiOperation注解的类,才生成接口文档 |
|
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) |
|
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) |
|
.paths(PathSelectors.any()) |
|
.build() |
|
.securitySchemes(Collections.singletonList(securityScheme())) |
|
.securityContexts(securityContexts()) |
|
.globalRequestParameters(setHeaderToken()); |
|
} |
|
|
|
/*** |
|
* oauth2配置 |
|
* 需要增加swagger授权回调地址 |
|
* http://localhost:8888/webjars/springfox-swagger-ui/o2c.html |
|
* @return |
|
*/ |
|
@Bean |
|
SecurityScheme securityScheme() { |
|
return new ApiKey(CommonConstant.X_ACCESS_TOKEN, CommonConstant.X_ACCESS_TOKEN, "header"); |
|
} |
|
|
|
/** |
|
* JWT token |
|
* |
|
* @return |
|
*/ |
|
private List<RequestParameter> setHeaderToken() { |
|
RequestParameterBuilder parameterBuilder = new RequestParameterBuilder(); |
|
List<RequestParameter> pars = new ArrayList<>(); |
|
// parameterBuilder |
|
// .name(CommonConstant.X_ACCESS_TOKEN).description("token") |
|
// .modelRef(new ModelRef("string")) |
|
// .parameterType("header") |
|
// .required(false).build(); |
|
|
|
parameterBuilder.name(CommonConstant.X_ACCESS_TOKEN) |
|
.description(CommonConstant.X_ACCESS_TOKEN) |
|
.query(parameterSpecBuilder -> { |
|
parameterSpecBuilder |
|
.defaultValue(CommonConstant.X_ACCESS_TOKEN) |
|
.model(modelSpecificationBuilder -> { |
|
modelSpecificationBuilder.scalarModel(ScalarType.STRING); |
|
}) |
|
.allowEmptyValue(Boolean.TRUE); |
|
}) |
|
.in(ParameterType.HEADER) |
|
.required(false); |
|
|
|
pars.add(parameterBuilder.build()); |
|
return pars; |
|
} |
|
|
|
/** |
|
* api文档的详细信息函数,注意这里的注解引用的是哪个 |
|
* |
|
* @return |
|
*/ |
|
private ApiInfo apiInfo() { |
|
return new ApiInfoBuilder() |
|
// //大标题 |
|
.title("DB Bastion Server 后台服务API接口文档") |
|
// 版本号 |
|
.version("1.0") |
|
// .termsOfServiceUrl("NO terms of service") |
|
// 描述 |
|
.description("后台API接口") |
|
// 作者 |
|
.contact(new Contact("niushuai233", "niushuai.cc", "shuai.niu@foxmail.com")) |
|
.license("The Apache License, Version 2.0") |
|
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") |
|
.build(); |
|
} |
|
|
|
/** |
|
* 新增 securityContexts 保持登录状态 |
|
*/ |
|
@SuppressWarnings("deprecation") |
|
private List<SecurityContext> securityContexts() { |
|
return new ArrayList( |
|
Collections.singleton(SecurityContext.builder() |
|
.securityReferences(defaultAuth()) |
|
.forPaths(PathSelectors.regex("^(?!auth).*$")) |
|
.build()) |
|
); |
|
} |
|
|
|
private List<SecurityReference> defaultAuth() { |
|
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); |
|
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; |
|
authorizationScopes[0] = authorizationScope; |
|
return new ArrayList( |
|
Collections.singleton(new SecurityReference(CommonConstant.X_ACCESS_TOKEN, authorizationScopes))); |
|
} |
|
|
|
|
|
}
|
|
|