当前位置:网站首页>(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. .
边栏推荐
- OpenCV中文文档4.0.0学习笔记(更新中……)
- 如何通过NFT GO,来简要判断、分析NFT市场?
- office回退版本,从2021到2019
- Typora提示【This beta version of Typora is expired, please download and install a newer version】的解决方案
- What is the "age limit" on tiktok and how to solve it?
- 面试官:哥们Go语言的读写锁了解多少?
- Cyclic multiple scatter
- Scatter chart - date
- 利用opencv 做一个简单的人脸识别
- TT ecosystem - cross border in-depth selection
猜你喜欢
![[FFH] openharmony gnawing paper growth plan -- Application of cjson in traditional c/s model](/img/a5/a8f4371a83fbd38c40aa7ba56a36d3.png)
[FFH] openharmony gnawing paper growth plan -- Application of cjson in traditional c/s model

【翻译】使用gRPC和REST的微服务架构中的集成挑战

Meta tags let search engines search your website

Houdini notes

office回退版本,从2021到2019

如何将CAD文件导入图新地球中,与影像地形倾斜模型准确叠加

Android system security - 5.3-apk V2 signature introduction

【FFH】OpenHarmony啃论文成长计划---cJSON在传统C/S模型下的应用

来阿里一年后我迎来了第一次工作变动....
![Typora prompt [this beta version of typora is expired, please download and install a new version]](/img/76/eb4ac7e717198a1bf613e8e71f9330.png)
Typora prompt [this beta version of typora is expired, please download and install a new version]
随机推荐
C language practice questions + Answers:
林业调查巡检数据采集解决方案
Office fallback version, from 2021 to 2019
What is tiktok creator fund and how to withdraw it?
Practice 4-6 number guessing game (15 points)
Interviewer: man, how much do you know about the read-write lock of go language?
Leetcode102-二叉树的层序遍历详解
Scatter chart - date
【汇编语言实战】(二)、编写一程序计算表达式w=v-(x+y+z-51)的值(含代码、过程截图)
Typora提示【This beta version of Typora is expired, please download and install a newer version】的解决方案
Houdini official HDA sidefx labs installation
How to configure env.js in multiple environments in uni app
Sword finger offer II 024. reverse linked list
Seven data show the impact of tiktok's combination of payment and organic content
Linked list - 24. Exchange nodes in the linked list in pairs
【基于ROS的URDF练习实例】四轮机器人与摄像头的使用
dp最长公共子序列详细版本(LCS)
After two days of tossing and turning, I finally wrote my first fluent app, which almost tortured me into a nervous breakdown
Tiktok's "online celebrity" was poached by Amazon and broadcast on Amazon live platform
利用opencv 做一个简单的人脸识别