当前位置:网站首页>(5) Cloud integrated gateway gateway +swagger documentation tool
(5) Cloud integrated gateway gateway +swagger documentation tool
2022-07-24 09:04:00 【Still mourning】
1. Preface
1.1 Why do I need to introduce a gateway ?
Unified the entrance of each service , Users only need to know where the gateway is , In addition, it may also have authentication 、 monitor 、 cache 、 Request management 、 Static response processing and other functions . On the other hand , Flexible routing strategies can also be developed at the gateway layer . For some specific API, We need to set up a white list 、 Routing rules and other restrictions
Be careful ! This section contains only gateway The introduction of gateway , And integration Swagger Documentation tool , The deep usage of gateway is not included for the time being
1.2 Swagger file
Document tool class , Docking and self-test are more convenient
2. Project iteration process
No update here , Please refer to previous articles
3. Project access
3.1 newly build gateway Gateway module
introduce pom.xml Related dependencies , Only major dependencies are introduced here
.....
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.1.1</version>
</dependency>
<!-- gateway -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2021.0.1.0</version>
</dependency>
<!-- <!– Support only SWAGGER Related dependencies , No UI A choice –>-->
<!-- <dependency>-->
<!-- <groupId>com.github.xiaoymin</groupId>-->
<!-- <artifactId>knife4j-micro-spring-boot-starter</artifactId>-->
<!-- <version>3.0.3</version>-->
<!-- </dependency>-->
<!-- Full version SWG rely on , belt UI A choice The gateway must be selected UI-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
.....Create a new cross domain profile CorsConfig
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // allow cookies Cross domain
config.addAllowedOrigin("*");// # Allow requests to be submitted to this server URI,* That all are allowed , stay SpringMVC in , If set to *, It will be automatically converted to... In the current request header Origin
config.addAllowedHeader("*");// # Allow access to header information ,* All
config.setMaxAge(18000L);// Preview the cache time of the request ( second ), In this period of time , For the same cross domain request, there will be no pre check
config.addAllowedMethod("OPTIONS");// The type of method allowed to submit the request ,* That all are allowed
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}newly build swagger Get policy configuration file swaggerProvider
/**
* @author zxg
* obtain Api-doc, namely SwaggerResources
*/
@Component
@Primary
public class SwaggerProvider implements SwaggerResourcesProvider {
public static final String API_URI = "/v3/api-docs";
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
this.routeLocator = routeLocator;
this.gatewayProperties = gatewayProperties;
}
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
// Take out gateway Of route
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
// Combined with configured route- route (Path), and route Filter , Only get the... Described in the enumeration route node
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
.forEach(routeDefinition -> routeDefinition.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("/**", API_URI)))
)
);
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("3.0");
return swaggerResource;
}
}newly build swagger Intercept configuration
/**
* @author zxg
* Swagger According to X-Forwarded-Prefix This Header To get BasePath, Add it to the interface path and host middle , Only in this way can the interface test be carried out normally
*/
@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
private static final String HEADER_NAME = "X-Forwarded-Prefix";
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
return chain.filter(exchange);
}
String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));
ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
return chain.filter(newExchange);
};
}
}newly build swagger Interface configuration
/**
* @author zxg
* because Gateway There is no configuration in the SwaggerConfig, And running Swagger-ui You need to rely on some interfaces , So my idea is to establish corresponding swagger-resource Endpoint
*/
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler {
@Autowired(required = false)
private SecurityConfiguration securityConfiguration;
@Autowired(required = false)
private UiConfiguration uiConfiguration;
private final SwaggerResourcesProvider swaggerResources;
@Autowired
public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
this.swaggerResources = swaggerResources;
}
@GetMapping("/configuration/security")
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@GetMapping("/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@GetMapping("")
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}stay application Configure service routing
Only the routing part is posted here
spring:
cloud:
gateway:
routes:
- id: user-server
uri: lb://user-server # use LoadBalanceClient Mode request , With lb:// start , The last one is registered in nacos Service name on
predicates:
- Path=/lb/user-server/**
filters:
- SwaggerHeaderFilter
- StripPrefix=1
3.2 Other services
To introduce the relevant pom.xml rely on
<!-- Support only SWAGGER Related dependencies , No UI A choice -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- <!– Full version SWG rely on , belt UI A choice –>-->
<!-- <dependency>-->
<!-- <groupId>com.github.xiaoymin</groupId>-->
<!-- <artifactId>knife4j-spring-boot-starter</artifactId>-->
<!-- <version>3.0.3</version>-->
<!-- </dependency>-->increase swagger The configuration file SwaggerConfig
/**
* @author zxg
*/
@EnableOpenApi
@Configuration
public class SwaggerConfig {
@Value("${spring.application.name}")
private String applicationName;
@Bean
public Docket createRestApi(){
return new Docket(DocumentationType.OAS_30)
.apiInfo(apiInfo())
.select()
// To have @Api Annotated Controller Generate API file
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.any())
.build()
.securitySchemes(unifiedAuth())
.securityContexts(securityContexts())
;
}
private static List<SecurityScheme> unifiedAuth() {
List<SecurityScheme> arrayList = new ArrayList();
arrayList.add(new ApiKey("Authorization", "Authorization", "header"));
return arrayList;
}
private List<SecurityContext> securityContexts() {
List<SecurityContext> securityContexts=new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("^(?!auth).*$"))
.build());
return securityContexts;
}
List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences=new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title(applicationName + " Interface document ")
.description(applicationName)
.contact(new Contact("xueliman", "www.xueliman-iov.com", ""))
.version("1.0")
.build();
}
@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);
}
}
};
}
}3.3 Start project
Access gateway swagger Address , The contents are as follows

4. summary
springcloud2021.x Version pair gateway The introduction of , And integration swagger file , Slightly different from the previous version , But not bad .
The above content is a summary of personal learning process and obtained by referring to online materials , If there is something wrong in the text , Welcome to advise , No joy, no spray. .
边栏推荐
- 使用分区的优点
- 超全总结:Go语言如何操作文件
- & 和 &&、| 和 || 的区别
- Realize page return to parent directory based on cookies
- 基于FPGA的VGA字符显示
- Tiktok's "online celebrity" was poached by Amazon and broadcast on Amazon live platform
- 来阿里一年后我迎来了第一次工作变动....
- Interviewer: man, how much do you know about the read-write lock of go language?
- How to open the port number of the server, and the corresponding port of common network services
- Office fallback version, from 2021 to 2019
猜你喜欢

【我的创作一周年纪念日】爱情是需要被纪念的,创作也是

One year after I came to Ali, I ushered in my first job change

How to use redis' publish subscribe (MQ) in.Netcore 3.1 project

Meta tags let search engines search your website

Paclitaxel loaded tpgs reduced albumin nanoparticles /ga-hsa gambogic acid human serum protein nanoparticles

Discuz论坛搭建详细过程,一看就懂

Tiktok's "online celebrity" was poached by Amazon and broadcast on Amazon live platform

Notify consumers after provider information changes in RPC

Run little turtle to test whether the ROS environment in the virtual machine is complete

Developing ebpf program with go language
随机推荐
TCP triple handshake connection combing
Matlab各函数说明
看了纪录片《埃达克岛的海盗宝藏》,想到我国历史上的遗失秘宝
How to import CAD files into the map new earth and accurately stack them with the image terrain tilt model
Treap
Online lover
Houdini 笔记
JUC powerful auxiliary class
排序入门—插入排序和希尔排序
【FFH】OpenHarmony啃论文成长计划---cJSON在传统C/S模型下的应用
Super complete summary: how to operate files in go language
阻塞队列BlockingQueue 源码解析(ArrayBQ和LinkedBQ)
Attack and defense world ----- confusion1
Android system security - 5.2-apk V1 signature introduction
Office fallback version, from 2021 to 2019
Typora提示【This beta version of Typora is expired, please download and install a newer version】的解决方案
【汇编语言实战】一元二次方程ax2+bx+c=0求解(含源码与过程截屏,可修改参数)
Rk3566 add project under external
Porting boa server on imx6ull
利用opencv 做一个简单的人脸识别