mirror of
https://gitee.com/youlaitech/youlai-mall.git
synced 2025-01-04 01:52:21 +08:00
refactor(youlai-gateway): 网关代码重构,swagger由webflux的注解式调整为函数式编程模型
This commit is contained in:
parent
ae0573c0ac
commit
1cb3ba4880
@ -1,4 +1,4 @@
|
||||
package com.youlai.gateway.kaptcha.config;
|
||||
package com.youlai.gateway.config;
|
||||
|
||||
import com.google.code.kaptcha.impl.DefaultKaptcha;
|
||||
import com.google.code.kaptcha.util.Config;
|
||||
@ -35,7 +35,7 @@ public class CaptchaConfig {
|
||||
// KAPTCHA_SESSION_KEY
|
||||
properties.setProperty("kaptcha.session.key", "kaptchaCodeMath");
|
||||
// 验证码文本生成器
|
||||
properties.setProperty("kaptcha.textproducer.impl", "com.youlai.gateway.kaptcha.KaptchaTextCreator");
|
||||
properties.setProperty("kaptcha.textproducer.impl", "com.youlai.gateway.util.KaptchaTextCreator");
|
||||
// 验证码文本字符间距 默认为2
|
||||
properties.setProperty("kaptcha.textproducer.char.space", "3");
|
||||
// 验证码文本字符长度 默认为5
|
@ -1,6 +1,6 @@
|
||||
package com.youlai.gateway.swagger;
|
||||
package com.youlai.gateway.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||
import org.springframework.cloud.gateway.route.RouteLocator;
|
||||
@ -14,22 +14,19 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author haoxr
|
||||
* @Date 2021-02-25 16:21
|
||||
* @Version 1.0.0
|
||||
* @ https://gitee.com/xiaoym/swagger-bootstrap-ui-demo/blob/master/knife4j-spring-cloud-gateway/service-doc/src/main/java/com/xiaominfo/swagger/service/doc/config/SwaggerResourceConfig.java
|
||||
* @author haoxr
|
||||
* @date 2022/5/17 16:21
|
||||
*/
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@Primary
|
||||
@AllArgsConstructor
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class SwaggerResourceConfig implements SwaggerResourcesProvider {
|
||||
|
||||
private final RouteLocator routeLocator;
|
||||
private final GatewayProperties gatewayProperties;
|
||||
|
||||
|
||||
@Override
|
||||
public List<SwaggerResource> get() {
|
||||
List<SwaggerResource> resources = new ArrayList<>();
|
@ -1,8 +1,9 @@
|
||||
package com.youlai.gateway.log;
|
||||
package com.youlai.gateway.filter;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.reactivestreams.Publisher;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
@ -51,7 +52,7 @@ import java.util.stream.Collectors;
|
||||
)
|
||||
@Component
|
||||
@Slf4j
|
||||
public class LogFilter implements GlobalFilter, Ordered {
|
||||
public class GatewayLogFilter implements GlobalFilter, Ordered {
|
||||
|
||||
private final List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();
|
||||
|
||||
@ -216,4 +217,81 @@ public class LogFilter implements GlobalFilter, Ordered {
|
||||
public int getOrder() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Data
|
||||
public static class TraceLog {
|
||||
|
||||
/**
|
||||
* 请求路径
|
||||
*/
|
||||
private String requestPath;
|
||||
|
||||
/**
|
||||
* 请求方法
|
||||
*/
|
||||
private String requestMethod;
|
||||
|
||||
/**
|
||||
* 查询参数
|
||||
*/
|
||||
private String queryParams;
|
||||
|
||||
/**
|
||||
* 请求载荷
|
||||
*/
|
||||
private String requestBody;
|
||||
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
private String responseBody;
|
||||
|
||||
/**
|
||||
* 请求时间
|
||||
*/
|
||||
private String requestTime;
|
||||
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
private String responseTime;
|
||||
|
||||
/**
|
||||
* 执行耗时(毫秒)
|
||||
*/
|
||||
private Long executeTime;
|
||||
|
||||
|
||||
public String toRequestString() {
|
||||
return
|
||||
"^^^^^^^^请求日志^^^^^^^^: " + requestMethod + ':' + requestPath + '\n' +
|
||||
"查询参数:" + queryParams + '\n' +
|
||||
"请求载荷:" + requestBody + '\n' +
|
||||
"请求时间:" + requestTime;
|
||||
}
|
||||
|
||||
public String toResponseString() {
|
||||
return
|
||||
"$$$$$$$$响应日志$$$$$$$$: " + requestMethod + ':' + requestPath + '\n' +
|
||||
"请求时间:" + requestTime + '\n' +
|
||||
"响应时间:" + responseTime + '\n' +
|
||||
"响应数据:" + responseBody + '\n' +
|
||||
"执行耗时:" + executeTime + "毫秒";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "========网关请求响应日志========\n" +
|
||||
"请求路径:" + requestPath + '\n' +
|
||||
"请求方法:" + requestMethod + '\n' +
|
||||
"请求参数:" + requestBody + '\n' +
|
||||
"响应数据:" + responseBody + '\n' +
|
||||
"请求时间:" + requestTime + '\n' +
|
||||
"响应时间:" + responseTime + '\n' +
|
||||
"执行耗时:" + executeTime + "毫秒";
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.youlai.gateway.security;
|
||||
package com.youlai.gateway.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
@ -1,4 +1,4 @@
|
||||
package com.youlai.gateway.kaptcha.handler;
|
||||
package com.youlai.gateway.handler;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.io.FastByteArrayOutputStream;
|
||||
@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
|
||||
* @author haoxr
|
||||
* @date 2021/10/4
|
||||
*/
|
||||
@Component
|
||||
@ -35,7 +35,7 @@ public class CaptchaHandler implements HandlerFunction<ServerResponse> {
|
||||
private final StringRedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
|
||||
public Mono<ServerResponse> handle(ServerRequest request) {
|
||||
// 生成验证码
|
||||
String capText = producer.createText();
|
||||
String capStr = capText.substring(0, capText.lastIndexOf("@"));
|
||||
@ -56,6 +56,6 @@ public class CaptchaHandler implements HandlerFunction<ServerResponse> {
|
||||
resultMap.put("uuid", uuid);
|
||||
resultMap.put("img", Base64.encode(os.toByteArray()));
|
||||
|
||||
return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(Result.success(resultMap)));
|
||||
return ServerResponse.ok().body(BodyInserters.fromValue(Result.success(resultMap)));
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.youlai.gateway.handler.swagger;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
|
||||
|
||||
|
||||
/**
|
||||
* 聚合各个服务的swagger接口
|
||||
*
|
||||
* @author haoxr
|
||||
* @date 2022/5/17 0:53
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SwaggerResourceHandler implements HandlerFunction<ServerResponse> {
|
||||
|
||||
private final SwaggerResourcesProvider swaggerResources;
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest request) {
|
||||
Mono<ServerResponse> responseMono = ServerResponse.ok()
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(BodyInserters
|
||||
.fromValue(swaggerResources.get()));
|
||||
return responseMono;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.youlai.gateway.handler.swagger;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import springfox.documentation.swagger.web.SecurityConfiguration;
|
||||
import springfox.documentation.swagger.web.SecurityConfigurationBuilder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* 权限处理器
|
||||
*
|
||||
* @author haoxr
|
||||
* @date 2022/5/17
|
||||
*/
|
||||
@Component
|
||||
public class SwaggerSecurityHandler implements HandlerFunction<ServerResponse> {
|
||||
|
||||
@Autowired(required = false)
|
||||
private SecurityConfiguration securityConfiguration;
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest request) {
|
||||
Mono<ServerResponse> responseMono = ServerResponse.ok()
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(BodyInserters
|
||||
.fromValue(Optional.ofNullable(securityConfiguration)
|
||||
.orElse(SecurityConfigurationBuilder.builder().build())));
|
||||
return responseMono;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.youlai.gateway.handler.swagger;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
import springfox.documentation.swagger.web.UiConfiguration;
|
||||
import springfox.documentation.swagger.web.UiConfigurationBuilder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
/**
|
||||
* UI处理器
|
||||
*
|
||||
* @author haoxr
|
||||
* @date 2022/5/17 0:51
|
||||
*/
|
||||
@Component
|
||||
public class SwaggerUiHandler implements HandlerFunction<ServerResponse> {
|
||||
|
||||
|
||||
@Autowired(required = false)
|
||||
private UiConfiguration uiConfiguration;
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest request) {
|
||||
Mono<ServerResponse> responseMono = ServerResponse.ok()
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.body(BodyInserters
|
||||
.fromValue(Optional.ofNullable(uiConfiguration)
|
||||
.orElse(UiConfigurationBuilder.builder().build())));
|
||||
return responseMono;
|
||||
}
|
||||
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package com.youlai.gateway.log;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 请求响应日志实体对象
|
||||
*
|
||||
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
|
||||
* @date 2022/4/28 16:54
|
||||
*/
|
||||
@Data
|
||||
public class TraceLog {
|
||||
|
||||
/**
|
||||
* 请求路径
|
||||
*/
|
||||
private String requestPath;
|
||||
|
||||
/**
|
||||
* 请求方法
|
||||
*/
|
||||
private String requestMethod;
|
||||
|
||||
/**
|
||||
* 查询参数
|
||||
*/
|
||||
private String queryParams;
|
||||
|
||||
/**
|
||||
* 请求载荷
|
||||
*/
|
||||
private String requestBody;
|
||||
|
||||
/**
|
||||
* 响应数据
|
||||
*/
|
||||
private String responseBody;
|
||||
|
||||
/**
|
||||
* 请求时间
|
||||
*/
|
||||
private String requestTime;
|
||||
|
||||
/**
|
||||
* 响应时间
|
||||
*/
|
||||
private String responseTime;
|
||||
|
||||
/**
|
||||
* 执行耗时(毫秒)
|
||||
*/
|
||||
private Long executeTime;
|
||||
|
||||
|
||||
public String toRequestString() {
|
||||
return
|
||||
"^^^^^^^^请求日志^^^^^^^^: " + requestMethod + ':' + requestPath + '\n' +
|
||||
"查询参数:" + queryParams + '\n' +
|
||||
"请求载荷:" + requestBody + '\n' +
|
||||
"请求时间:" + requestTime;
|
||||
}
|
||||
|
||||
public String toResponseString() {
|
||||
return
|
||||
"$$$$$$$$响应日志$$$$$$$$: " + requestMethod + ':' + requestPath + '\n' +
|
||||
"请求时间:" + requestTime + '\n' +
|
||||
"响应时间:" + responseTime + '\n' +
|
||||
"响应数据:" + responseBody + '\n' +
|
||||
"执行耗时:" + executeTime + "毫秒";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "========网关请求响应日志========\n" +
|
||||
"请求路径:" + requestPath + '\n' +
|
||||
"请求方法:" + requestMethod + '\n' +
|
||||
"请求参数:" + requestBody + '\n' +
|
||||
"响应数据:" + responseBody + '\n' +
|
||||
"请求时间:" + requestTime + '\n' +
|
||||
"响应时间:" + responseTime + '\n' +
|
||||
"执行耗时:" + executeTime + "毫秒";
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package com.youlai.gateway.router;
|
||||
|
||||
import com.youlai.gateway.kaptcha.handler.CaptchaHandler;
|
||||
import com.youlai.gateway.handler.CaptchaHandler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
@ -10,16 +10,16 @@ import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
/**
|
||||
* 图片验证码路由
|
||||
* 验证码路由
|
||||
*
|
||||
* @author <a href="mailto:xianrui0365@163.com">haoxr</a>
|
||||
* @date 2021/10/4
|
||||
* @author haoxr
|
||||
* @date 2022/5/16
|
||||
*/
|
||||
@Configuration
|
||||
public class CaptchaRouter {
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> routeFunction(CaptchaHandler captchaHandler) {
|
||||
public RouterFunction<ServerResponse> captchaRouterFunction(CaptchaHandler captchaHandler) {
|
||||
return RouterFunctions
|
||||
.route(RequestPredicates.GET("/captcha")
|
||||
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), captchaHandler::handle);
|
||||
|
@ -0,0 +1,46 @@
|
||||
package com.youlai.gateway.router;
|
||||
|
||||
import com.youlai.gateway.handler.swagger.SwaggerResourceHandler;
|
||||
import com.youlai.gateway.handler.swagger.SwaggerSecurityHandler;
|
||||
import com.youlai.gateway.handler.swagger.SwaggerUiHandler;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
/**
|
||||
* Swagger路由
|
||||
*
|
||||
* @author haoxr
|
||||
* @date 2022/5/16 16:34
|
||||
*/
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class SwaggerRouter {
|
||||
|
||||
/**
|
||||
* 聚合各个服务的swagger接口
|
||||
*/
|
||||
private final SwaggerResourceHandler swaggerResourceHandler;
|
||||
/**
|
||||
* 权限处理器
|
||||
*/
|
||||
private final SwaggerSecurityHandler swaggerSecurityHandler;
|
||||
/**
|
||||
* UI处理器
|
||||
*/
|
||||
private final SwaggerUiHandler swaggerUiHandler;
|
||||
|
||||
@Bean
|
||||
public RouterFunction<ServerResponse> swaggerRouterFunction() {
|
||||
return RouterFunctions
|
||||
.route(RequestPredicates.GET("/swagger-resources/configuration/security").and(RequestPredicates.accept(MediaType.ALL)), swaggerSecurityHandler::handle)
|
||||
.andRoute(RequestPredicates.GET("/swagger-resources/configuration/ui").and(RequestPredicates.accept(MediaType.ALL)), swaggerUiHandler::handle)
|
||||
.andRoute(RequestPredicates.GET("/swagger-resources").and(RequestPredicates.accept(MediaType.ALL)), swaggerResourceHandler::handle);
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.youlai.gateway.swagger;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import reactor.core.publisher.Mono;
|
||||
import springfox.documentation.swagger.web.*;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author xianrui
|
||||
* @Date 2021-02-25 16:34
|
||||
* @Version 1.0.0
|
||||
* @ https://gitee.com/xiaoym/swagger-bootstrap-ui-demo/blob/masterknife4j-spring-cloud-gateway/service-doc/src/main/java/com/xiaominfo/swagger/service/doc/handler/SwaggerHandler.java
|
||||
*/
|
||||
@RestController
|
||||
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("/swagger-resources/configuration/security")
|
||||
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
|
||||
return Mono.just(new ResponseEntity<>(
|
||||
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
|
||||
}
|
||||
|
||||
@GetMapping("/swagger-resources/configuration/ui")
|
||||
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
|
||||
return Mono.just(new ResponseEntity<>(
|
||||
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
|
||||
}
|
||||
|
||||
@GetMapping("/swagger-resources")
|
||||
public Mono<ResponseEntity> swaggerResources() {
|
||||
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.youlai.gateway.kaptcha;
|
||||
package com.youlai.gateway.util;
|
||||
|
||||
import com.google.code.kaptcha.text.impl.DefaultTextCreator;
|
||||
|
@ -14,8 +14,10 @@ import reactor.core.publisher.Mono;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* @Author hxr
|
||||
* @Date 2021-01-29 13:30
|
||||
* 异常响应工具类
|
||||
*
|
||||
* @Author haoxr
|
||||
* @Date 2021/01/29 13:30
|
||||
*/
|
||||
public class ResponseUtils {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user