Commit 45276d37972c268140c2d40274697ca8d628f88b

Authored by miaoguoxin
1 parent 98f0de9f

优化异常处理

gateway-business/pom.xml
... ... @@ -16,6 +16,5 @@
16 16 <artifactId>gateway-core</artifactId>
17 17 <groupId>com.diligrp</groupId>
18 18 </dependency>
19   -
20 19 </dependencies>
21 20 </project>
22 21 \ No newline at end of file
... ...
gateway-business/src/main/java/com/diligrp/xtrade/business/XtradeGatewayApplication.java
1 1 package com.diligrp.xtrade.business;
2 2  
  3 +import io.netty.util.ResourceLeakDetector;
3 4 import org.mybatis.spring.annotation.MapperScan;
4 5 import org.springframework.boot.SpringApplication;
5 6 import org.springframework.boot.autoconfigure.SpringBootApplication;
... ... @@ -15,6 +16,7 @@ import org.springframework.cloud.context.config.annotation.RefreshScope;
15 16 public class XtradeGatewayApplication {
16 17  
17 18 public static void main(String[] args) {
  19 + ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);
18 20 SpringApplication.run(XtradeGatewayApplication.class, args);
19 21 }
20 22  
... ...
gateway-business/src/main/java/com/diligrp/xtrade/business/controller/TestController.java
... ... @@ -26,7 +26,7 @@ public class TestController {
26 26 private String interval;
27 27  
28 28 @GetMapping("/test_dynamic")
29   - public Message<String> test1( TestRequestDto testRequestDto) {
  29 + public Message<String> test1(@Validated TestRequestDto testRequestDto) {
30 30 throw new RuntimeException("fffff");
31 31 }
32 32 }
... ...
gateway-core/pom.xml
... ... @@ -17,6 +17,10 @@
17 17 <artifactId>xtrade-shared-spring-boot-starter</artifactId>
18 18 </dependency>
19 19 <dependency>
  20 + <groupId>org.springframework.boot</groupId>
  21 + <artifactId>spring-boot-configuration-processor</artifactId>
  22 + </dependency>
  23 + <dependency>
20 24 <groupId>org.springframework.cloud</groupId>
21 25 <artifactId>spring-cloud-starter-gateway</artifactId>
22 26 </dependency>
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/api/ApiManager.java
1 1 package com.diligrp.xtrade.core.api;
2 2  
  3 +import com.diligrp.xtrade.core.common.utils.PathUtils;
3 4 import com.diligrp.xtrade.core.config.property.AuthPathProperties;
4 5 import org.springframework.beans.factory.annotation.Autowired;
5 6 import org.springframework.http.server.PathContainer;
... ... @@ -20,12 +21,6 @@ public class ApiManager {
20 21  
21 22 public boolean isExcludePathMatch(String path) {
22 23 //没有配置排除path的话,表示不拦截任何path
23   - PathContainer pathContainer = PathContainer.parsePath(path);
24   - return Optional.ofNullable(authPathProperties.getExcludePathPatterns())
25   - .map(pathPatterns -> pathPatterns
26   - .stream()
27   - .anyMatch(pattern -> pattern.matches(pathContainer)))
28   - .orElse(true);
  24 + return PathUtils.isUriMatch(path, authPathProperties.getExcludePathPatterns());
29 25 }
30   -
31 26 }
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/config/ExceptionConfiguration.java
1   -package com.diligrp.xtrade.core.config;
2   -
3   -import com.diligrp.xtrade.core.exception.GlobalGatewayErrorHandler;
4   -import org.springframework.beans.factory.ObjectProvider;
5   -import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
6   -import org.springframework.context.annotation.Bean;
7   -import org.springframework.context.annotation.Configuration;
8   -import org.springframework.context.annotation.Primary;
9   -import org.springframework.core.Ordered;
10   -import org.springframework.core.annotation.Order;
11   -import org.springframework.http.codec.ServerCodecConfigurer;
12   -import org.springframework.web.reactive.result.view.ViewResolver;
13   -
14   -import java.util.Collections;
15   -import java.util.List;
16   -
17   -/**
18   - * @Auther: miaoguoxin
19   - * @Date: 2018/12/12 21:53
20   - * @Description: 全局异常处理配置
21   - */
22   -@Configuration
23   -public class ExceptionConfiguration {
24   - @Primary
25   - @Bean
26   - @Order(Ordered.HIGHEST_PRECEDENCE)
27   - public ErrorWebExceptionHandler errorWebExceptionHandler(ObjectProvider<List<ViewResolver>> viewResolversProvider,
28   - ServerCodecConfigurer serverCodecConfigurer) {
29   - GlobalGatewayErrorHandler jsonExceptionHandler = new GlobalGatewayErrorHandler();
30   - jsonExceptionHandler.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList));
31   - jsonExceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters());
32   - jsonExceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders());
33   - return jsonExceptionHandler;
34   - }
35   -
36   -}
  1 +//package com.diligrp.xtrade.core.config;
  2 +//
  3 +//import com.diligrp.xtrade.core.exception.GlobalGatewayErrorHandler;
  4 +//import org.springframework.beans.factory.ObjectProvider;
  5 +//import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
  6 +//import org.springframework.context.annotation.Bean;
  7 +//import org.springframework.context.annotation.Configuration;
  8 +//import org.springframework.context.annotation.Primary;
  9 +//import org.springframework.core.Ordered;
  10 +//import org.springframework.core.annotation.Order;
  11 +//import org.springframework.http.codec.ServerCodecConfigurer;
  12 +//import org.springframework.web.reactive.result.view.ViewResolver;
  13 +//
  14 +//import java.util.Collections;
  15 +//import java.util.List;
  16 +//
  17 +///**
  18 +// * @Auther: miaoguoxin
  19 +// * @Date: 2018/12/12 21:53
  20 +// * @Description: 全局异常处理配置
  21 +// */
  22 +//@Configuration
  23 +//public class ExceptionConfiguration {
  24 +//// @Primary
  25 +//// @Bean
  26 +//// @Order(Ordered.HIGHEST_PRECEDENCE)
  27 +// public ErrorWebExceptionHandler errorWebExceptionHandler(ObjectProvider<List<ViewResolver>> viewResolversProvider,
  28 +// ServerCodecConfigurer serverCodecConfigurer) {
  29 +// GlobalGatewayErrorHandler jsonExceptionHandler = new GlobalGatewayErrorHandler();
  30 +// jsonExceptionHandler.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList));
  31 +// jsonExceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters());
  32 +// jsonExceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders());
  33 +// return jsonExceptionHandler;
  34 +// }
  35 +//
  36 +//}
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/config/property/DispatchProperties.java
... ... @@ -13,9 +13,6 @@ public class DispatchProperties {
13 13 /** 扫描包路径 */
14 14 private String[] aggregationScanPackages;
15 15  
16   - public DispatchProperties(String[] aggregationScanPackages) {
17   - this.aggregationScanPackages = aggregationScanPackages;
18   - }
19 16  
20 17 public String[] getAggregationScanPackages() {
21 18 return aggregationScanPackages;
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/exception/GlobalGatewayErrorHandler.java
1   -package com.diligrp.xtrade.core.exception;
2   -
3   -import com.diligrp.xtrade.core.common.constant.GatewayConst;
4   -import com.diligrp.xtrade.shared.domain.Message;
5   -import com.diligrp.xtrade.shared.type.ErrorCode;
6   -import com.diligrp.xtrade.shared.util.JsonUtils;
7   -import org.slf4j.Logger;
8   -import org.slf4j.LoggerFactory;
9   -import org.springframework.beans.factory.annotation.Autowired;
10   -import org.springframework.boot.web.reactive.error.ErrorAttributes;
11   -import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
12   -import org.springframework.http.HttpStatus;
13   -import org.springframework.http.MediaType;
14   -import org.springframework.http.codec.HttpMessageReader;
15   -import org.springframework.http.codec.HttpMessageWriter;
16   -import org.springframework.http.server.reactive.ServerHttpRequest;
17   -import org.springframework.util.Assert;
18   -import org.springframework.web.reactive.function.BodyInserters;
19   -import org.springframework.web.reactive.function.server.RequestPredicates;
20   -import org.springframework.web.reactive.function.server.RouterFunctions;
21   -import org.springframework.web.reactive.function.server.ServerRequest;
22   -import org.springframework.web.reactive.function.server.ServerResponse;
23   -import org.springframework.web.reactive.result.view.ViewResolver;
24   -import org.springframework.web.server.ResponseStatusException;
25   -import org.springframework.web.server.ServerWebExchange;
26   -import reactor.core.publisher.Mono;
27   -
28   -import java.util.Collections;
29   -import java.util.List;
30   -import java.util.Map;
31   -
32   -
33   -/**
34   - * @Auther: miaoguoxin
35   - * @Date: 2020/04/13 10:55
36   - * @Description: 处理网关本身抛出的异常
37   - */
38   -public class GlobalGatewayErrorHandler implements ErrorWebExceptionHandler {
39   - private static final Logger log = LoggerFactory.getLogger(GlobalGatewayErrorHandler.class);
40   - @Autowired
41   - private ErrorAttributes errorAttributes;
42   - /**
43   - * MessageReader
44   - */
45   - private List<HttpMessageReader<?>> messageReaders = Collections.emptyList();
46   -
47   - /**
48   - * MessageWriter
49   - */
50   - private List<HttpMessageWriter<?>> messageWriters = Collections.emptyList();
51   -
52   - /**
53   - * ViewResolvers
54   - */
55   - private List<ViewResolver> viewResolvers = Collections.emptyList();
56   -
57   - /**
58   - * 存储处理异常后的信息
59   - */
60   - private ThreadLocal<Map<String, Object>> exceptionHandlerResult = new ThreadLocal<>();
61   -
62   - /**
63   - * 参考AbstractErrorWebExceptionHandler
64   - */
65   - public void setViewResolvers(List<ViewResolver> viewResolvers) {
66   - this.viewResolvers = viewResolvers;
67   - }
68   -
69   - /**
70   - * 参考AbstractErrorWebExceptionHandler
71   - */
72   - public void setMessageWriters(List<HttpMessageWriter<?>> messageWriters) {
73   - Assert.notNull(messageWriters, "'messageWriters' must not be null");
74   - this.messageWriters = messageWriters;
75   - }
76   -
77   - /**
78   - * 参考AbstractErrorWebExceptionHandler
79   - */
80   - public void setMessageReaders(List<HttpMessageReader<?>> messageReaders) {
81   - Assert.notNull(messageReaders, "'messageReaders' must not be null");
82   - this.messageReaders = messageReaders;
83   - }
84   -
85   -
86   - @Override
87   - public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
88   - ServerHttpRequest request = exchange.getRequest();
89   - // Map<String, Object> result = this.getHttpResult(httpStatus);
90   - //参考AbstractErrorWebExceptionHandler
91   - if (exchange.getResponse().isCommitted()) {
92   - return Mono.error(ex);
93   - }
94   - errorAttributes.storeErrorInformation(ex, exchange);
95   - ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders);
96   - return RouterFunctions
97   - .route(RequestPredicates.all(), request1 -> renderErrorResponse(request1, exchange))
98   - .route(newRequest)
99   - .switchIfEmpty(Mono.error(ex))
100   - .flatMap((handler) -> handler.handle(newRequest))
101   - .flatMap((response) -> write(exchange, response));
102   - }
103   -
104   -
105   - /**
106   - * 参考DefaultErrorWebExceptionHandler
107   - */
108   - private Mono<ServerResponse> renderErrorResponse(ServerRequest request, ServerWebExchange exchange) {
109   - Throwable error = errorAttributes.getError(request);
110   - Message<Object> message = handleException(error);
111   - exchange.getAttributes().putIfAbsent(GatewayConst.GATEWAY_EXCEPTION_ATTR, error);
112   - exchange.getAttributes().putIfAbsent(GatewayConst.CACHED_RESPONSE_BODY_STR_ATTR, JsonUtils.toJsonString(message));
113   - return ServerResponse.status(HttpStatus.OK)
114   - .contentType(MediaType.APPLICATION_JSON)
115   - .body(BodyInserters.fromValue(message));
116   - }
117   -
118   - private static Message<Object> handleException(Throwable ex) {
119   - if (ex instanceof GatewayDispatchException) {
120   - GatewayDispatchException dispatchEx = (GatewayDispatchException) ex;
121   - if (dispatchEx.getCause() != null) {
122   - return handleException(dispatchEx.getCause());
123   - } else {
124   - return Message.failure(
125   - ErrorCode.UNKNOWN_ERROR.getCode(), ErrorCode.UNKNOWN_ERROR.getName());
126   - }
127   - } else if (ex instanceof ResponseStatusException) {
128   - int statusCode = ((ResponseStatusException) ex).getStatus().value();
129   - return Message.failure(statusCode, ex.getMessage());
130   - } else if (ex instanceof GatewayParamNotValidException) {
131   - return Message.failure(
132   - ErrorCode.ILLEGAL_PARAMS.getCode(), ex.getMessage());
133   - } else {
134   - return Message.failure(
135   - ErrorCode.UNKNOWN_ERROR.getCode(), ErrorCode.UNKNOWN_ERROR.getName());
136   - }
137   - }
138   -
139   - /**
140   - * 参考AbstractErrorWebExceptionHandler
141   - */
142   - private Mono<? extends Void> write(ServerWebExchange exchange,
143   - ServerResponse response) {
144   - exchange.getResponse().getHeaders()
145   - .setContentType(response.headers().getContentType());
146   - return response.writeTo(exchange, new ResponseContext());
147   - }
148   -
149   -
150   - /**
151   - * 参考AbstractErrorWebExceptionHandler
152   - */
153   - private class ResponseContext implements ServerResponse.Context {
154   -
155   - @Override
156   - public List<HttpMessageWriter<?>> messageWriters() {
157   - return GlobalGatewayErrorHandler.this.messageWriters;
158   - }
159   -
160   - @Override
161   - public List<ViewResolver> viewResolvers() {
162   - return GlobalGatewayErrorHandler.this.viewResolvers;
163   - }
164   -
165   - }
166   -
167   -}
  1 +//package com.diligrp.xtrade.core.exception;
  2 +//
  3 +//import com.diligrp.xtrade.core.common.constant.GatewayConst;
  4 +//import com.diligrp.xtrade.shared.domain.Message;
  5 +//import com.diligrp.xtrade.shared.type.ErrorCode;
  6 +//import com.diligrp.xtrade.shared.util.JsonUtils;
  7 +//import org.springframework.beans.factory.annotation.Autowired;
  8 +//import org.springframework.boot.web.reactive.error.ErrorAttributes;
  9 +//import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
  10 +//import org.springframework.http.HttpStatus;
  11 +//import org.springframework.http.MediaType;
  12 +//import org.springframework.http.codec.HttpMessageReader;
  13 +//import org.springframework.http.codec.HttpMessageWriter;
  14 +//import org.springframework.http.server.reactive.ServerHttpRequest;
  15 +//import org.springframework.util.Assert;
  16 +//import org.springframework.web.reactive.function.BodyInserters;
  17 +//import org.springframework.web.reactive.function.server.RequestPredicates;
  18 +//import org.springframework.web.reactive.function.server.RouterFunctions;
  19 +//import org.springframework.web.reactive.function.server.ServerRequest;
  20 +//import org.springframework.web.reactive.function.server.ServerResponse;
  21 +//import org.springframework.web.reactive.result.view.ViewResolver;
  22 +//import org.springframework.web.server.ResponseStatusException;
  23 +//import org.springframework.web.server.ServerWebExchange;
  24 +//import reactor.core.publisher.Mono;
  25 +//
  26 +//import java.util.Collections;
  27 +//import java.util.List;
  28 +//import java.util.Map;
  29 +//
  30 +//
  31 +///**
  32 +// * @Auther: miaoguoxin
  33 +// * @Date: 2020/04/13 10:55
  34 +// * @Description: 处理网关本身抛出的异常
  35 +// */
  36 +//public class GlobalGatewayErrorHandler implements ErrorWebExceptionHandler {
  37 +// @Autowired
  38 +// private ErrorAttributes errorAttributes;
  39 +// /**
  40 +// * MessageReader
  41 +// */
  42 +// private List<HttpMessageReader<?>> messageReaders = Collections.emptyList();
  43 +//
  44 +// /**
  45 +// * MessageWriter
  46 +// */
  47 +// private List<HttpMessageWriter<?>> messageWriters = Collections.emptyList();
  48 +//
  49 +// /**
  50 +// * ViewResolvers
  51 +// */
  52 +// private List<ViewResolver> viewResolvers = Collections.emptyList();
  53 +//
  54 +// /**
  55 +// * 存储处理异常后的信息
  56 +// */
  57 +// private ThreadLocal<Map<String, Object>> exceptionHandlerResult = new ThreadLocal<>();
  58 +//
  59 +// /**
  60 +// * 参考AbstractErrorWebExceptionHandler
  61 +// */
  62 +// public void setViewResolvers(List<ViewResolver> viewResolvers) {
  63 +// this.viewResolvers = viewResolvers;
  64 +// }
  65 +//
  66 +// /**
  67 +// * 参考AbstractErrorWebExceptionHandler
  68 +// */
  69 +// public void setMessageWriters(List<HttpMessageWriter<?>> messageWriters) {
  70 +// Assert.notNull(messageWriters, "'messageWriters' must not be null");
  71 +// this.messageWriters = messageWriters;
  72 +// }
  73 +//
  74 +// /**
  75 +// * 参考AbstractErrorWebExceptionHandler
  76 +// */
  77 +// public void setMessageReaders(List<HttpMessageReader<?>> messageReaders) {
  78 +// Assert.notNull(messageReaders, "'messageReaders' must not be null");
  79 +// this.messageReaders = messageReaders;
  80 +// }
  81 +//
  82 +//
  83 +// @Override
  84 +// public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
  85 +// ServerHttpRequest request = exchange.getRequest();
  86 +// // Map<String, Object> result = this.getHttpResult(httpStatus);
  87 +// //参考AbstractErrorWebExceptionHandler
  88 +// if (exchange.getResponse().isCommitted()) {
  89 +// return Mono.error(ex);
  90 +// }
  91 +// errorAttributes.storeErrorInformation(ex, exchange);
  92 +// ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders);
  93 +// return RouterFunctions
  94 +// .route(RequestPredicates.all(), request1 -> renderErrorResponse(request1, exchange))
  95 +// .route(newRequest)
  96 +// .switchIfEmpty(Mono.error(ex))
  97 +// .flatMap((handler) -> handler.handle(newRequest))
  98 +// .flatMap((response) -> write(exchange, response));
  99 +// }
  100 +//
  101 +//
  102 +// /**
  103 +// * 参考DefaultErrorWebExceptionHandler
  104 +// */
  105 +// private Mono<ServerResponse> renderErrorResponse(ServerRequest request, ServerWebExchange exchange) {
  106 +// Throwable error = errorAttributes.getError(request);
  107 +// Message<Object> message = handleException(error);
  108 +// exchange.getAttributes().putIfAbsent(GatewayConst.GATEWAY_EXCEPTION_ATTR, error);
  109 +// exchange.getAttributes().putIfAbsent(GatewayConst.CACHED_RESPONSE_BODY_STR_ATTR, JsonUtils.toJsonString(message));
  110 +// return ServerResponse.status(HttpStatus.OK)
  111 +// .contentType(MediaType.APPLICATION_JSON)
  112 +// .body(BodyInserters.fromValue(message));
  113 +// }
  114 +//
  115 +// private static Message<Object> handleException(Throwable ex) {
  116 +// if (ex instanceof GatewayDispatchException) {
  117 +// GatewayDispatchException dispatchEx = (GatewayDispatchException) ex;
  118 +// if (dispatchEx.getCause() != null) {
  119 +// return handleException(dispatchEx.getCause());
  120 +// } else {
  121 +// return Message.failure(
  122 +// ErrorCode.UNKNOWN_ERROR.getCode(), ErrorCode.UNKNOWN_ERROR.getName());
  123 +// }
  124 +// } else if (ex instanceof ResponseStatusException) {
  125 +// int statusCode = ((ResponseStatusException) ex).getStatus().value();
  126 +// return Message.failure(statusCode, ex.getMessage());
  127 +// } else if (ex instanceof GatewayParamNotValidException) {
  128 +// return Message.failure(
  129 +// ErrorCode.ILLEGAL_PARAMS.getCode(), ex.getMessage());
  130 +// } else {
  131 +// return Message.failure(
  132 +// ErrorCode.UNKNOWN_ERROR.getCode(), ErrorCode.UNKNOWN_ERROR.getName());
  133 +// }
  134 +// }
  135 +//
  136 +// /**
  137 +// * 参考AbstractErrorWebExceptionHandler
  138 +// */
  139 +// private Mono<? extends Void> write(ServerWebExchange exchange,
  140 +// ServerResponse response) {
  141 +// exchange.getResponse().getHeaders()
  142 +// .setContentType(response.headers().getContentType());
  143 +// return response.writeTo(exchange, new ResponseContext());
  144 +// }
  145 +//
  146 +//
  147 +// /**
  148 +// * 参考AbstractErrorWebExceptionHandler
  149 +// */
  150 +// private class ResponseContext implements ServerResponse.Context {
  151 +//
  152 +// @Override
  153 +// public List<HttpMessageWriter<?>> messageWriters() {
  154 +// return GlobalGatewayErrorHandler.this.messageWriters;
  155 +// }
  156 +//
  157 +// @Override
  158 +// public List<ViewResolver> viewResolvers() {
  159 +// return GlobalGatewayErrorHandler.this.viewResolvers;
  160 +// }
  161 +//
  162 +// }
  163 +//
  164 +//}
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/filters/global/CacheRequestBodyGlobalFilter.java
... ... @@ -51,7 +51,6 @@ public class CacheRequestBodyGlobalFilter implements GlobalFilter, Ordered {
51 51 headers.putAll(exchange.getRequest().getHeaders());
52 52 //由bodyInserter重新设置content-length
53 53 headers.remove(HttpHeaders.CONTENT_LENGTH);
54   -
55 54 CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(
56 55 exchange, headers);
57 56 return bodyInserter.insert(outputMessage, new BodyInserterContext())
... ... @@ -83,6 +82,7 @@ public class CacheRequestBodyGlobalFilter implements GlobalFilter, Ordered {
83 82 public Flux<DataBuffer> getBody() {
84 83 return outputMessage.getBody();
85 84 }
  85 +
86 86 };
87 87 }
88 88  
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/filters/global/ResponseReadBodyGlobalFilter.java
1 1 package com.diligrp.xtrade.core.filters.global;
2 2  
  3 +import com.diligrp.xtrade.core.common.constant.GatewayConst;
3 4 import com.diligrp.xtrade.core.support.dispatch.MappingRegister;
4 5 import org.reactivestreams.Publisher;
5 6 import org.slf4j.Logger;
... ... @@ -7,6 +8,7 @@ import org.slf4j.LoggerFactory;
7 8 import org.springframework.cloud.gateway.filter.GatewayFilterChain;
8 9 import org.springframework.cloud.gateway.filter.GlobalFilter;
9 10 import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
  11 +import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
10 12 import org.springframework.core.Ordered;
11 13 import org.springframework.core.io.buffer.DataBuffer;
12 14 import org.springframework.http.HttpHeaders;
... ... @@ -28,8 +30,6 @@ import java.util.List;
28 30 import java.util.Objects;
29 31 import java.util.function.BiFunction;
30 32  
31   -import static com.diligrp.xtrade.core.common.constant.GatewayConst.CACHED_RESPONSE_BODY_STR_ATTR;
32   -import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR;
33 33  
34 34 /**
35 35 * @auther: miaoguoxin
... ... @@ -67,14 +67,14 @@ public class ResponseReadBodyGlobalFilter implements GlobalFilter, Ordered {
67 67 */
68 68 private BodyHandlerServerHttpResponseDecorator.BodyHandlerFunction initBodyHandler(ServerWebExchange exchange, long startTime) {
69 69 return (resp, body) -> {
70   - MediaType originalResponseContentType = MediaType.parseMediaType(Objects.requireNonNull(exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR)));
  70 + MediaType originalResponseContentType = MediaType.parseMediaType(Objects.requireNonNull(exchange.getAttribute(ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR)));
71 71 HttpHeaders httpHeaders = new HttpHeaders();
72 72 httpHeaders.setContentType(originalResponseContentType);
73 73  
74 74 ClientResponse clientResponse = this.prepareClientResponse(exchange.getResponse().getStatusCode(), body, httpHeaders);
75 75 Mono<String> bodyMono = clientResponse.bodyToMono(String.class);
76 76 return bodyMono.flatMap(respBody -> {
77   - exchange.getAttributes().putIfAbsent(CACHED_RESPONSE_BODY_STR_ATTR,respBody);
  77 + exchange.getAttributes().putIfAbsent(GatewayConst.CACHED_RESPONSE_BODY_STR_ATTR,respBody);
78 78 HttpHeaders headers = resp.getHeaders();
79 79 //特别声明:响应体改变必须设置contentLength,且长度要保持一致,(经过测试,如果过短则会截断,过长则会导致超时。)
80 80 headers.setContentLength(respBody.getBytes(StandardCharsets.UTF_8).length);
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/filters/web/FacadeWebFilter.java
1 1 package com.diligrp.xtrade.core.filters.web;
2 2  
  3 +import com.diligrp.xtrade.core.common.constant.GatewayConst;
  4 +import com.diligrp.xtrade.core.common.utils.ResponseUtils;
  5 +import com.diligrp.xtrade.core.exception.GatewayDispatchException;
  6 +import com.diligrp.xtrade.core.exception.GatewayParamNotValidException;
3 7 import com.diligrp.xtrade.core.support.ApiMetricsCollector;
4 8 import com.diligrp.xtrade.core.support.ApiMetricsInfo;
5 9 import com.diligrp.xtrade.core.support.context.ReactiveExchangeContextHolder;
  10 +import com.diligrp.xtrade.shared.domain.Message;
6 11 import com.diligrp.xtrade.shared.type.ErrorCode;
7 12 import com.diligrp.xtrade.shared.util.JsonUtils;
8 13 import org.slf4j.Logger;
... ... @@ -10,6 +15,7 @@ import org.slf4j.LoggerFactory;
10 15 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
11 16 import org.springframework.http.server.reactive.ServerHttpRequest;
12 17 import org.springframework.stereotype.Component;
  18 +import org.springframework.web.server.ResponseStatusException;
13 19 import org.springframework.web.server.ServerWebExchange;
14 20 import org.springframework.web.server.WebFilter;
15 21 import org.springframework.web.server.WebFilterChain;
... ... @@ -28,6 +34,12 @@ public class FacadeWebFilter implements WebFilter {
28 34  
29 35 @Override
30 36 public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
  37 +// Object handlerMethod = requestMappingHandlerMapping.getHandler(exchange).toProcessor().peek();
  38 +// //注意跨域时的配置,跨域时浏览器会先发送一个option请求,这时候getHandler不会时真正的HandlerMethod
  39 +// if(handlerMethod instanceof HandlerMethod){
  40 +// Valid valid = ((HandlerMethod) handlerMethod).getMethodAnnotation(Valid.class);
  41 +// //do your logic
  42 +// }
31 43 long startTime = System.currentTimeMillis();
32 44 ServerHttpRequest request = exchange.getRequest();
33 45 String path = request.getURI().getRawPath();
... ... @@ -35,10 +47,41 @@ public class FacadeWebFilter implements WebFilter {
35 47 return exchange.getResponse().setComplete();
36 48 }
37 49 ReactiveExchangeContextHolder.put(exchange);
38   - return chain.filter(exchange).doFinally(signalType -> {
39   - ReactiveExchangeContextHolder.remove();
40   - this.recordApiMetrics(exchange, startTime);
41   - });
  50 + return chain.filter(exchange)
  51 + .onErrorResume(throwable -> {
  52 + Message<Object> message = handleException(throwable);
  53 + exchange.getAttributes().putIfAbsent(GatewayConst.GATEWAY_EXCEPTION_ATTR, throwable);
  54 + exchange.getAttributes().putIfAbsent(GatewayConst.CACHED_RESPONSE_BODY_STR_ATTR, JsonUtils.toJsonString(message));
  55 + return ResponseUtils.writeResponse(exchange.getResponse(), message);
  56 + })
  57 + .doFinally(signalType -> {
  58 + ReactiveExchangeContextHolder.remove();
  59 + this.recordApiMetrics(exchange, startTime);
  60 + });
  61 + }
  62 +
  63 +
  64 + private static Message<Object> handleException(Throwable ex) {
  65 + if (ex instanceof GatewayDispatchException) {
  66 + GatewayDispatchException dispatchEx = (GatewayDispatchException) ex;
  67 + if (dispatchEx.getCause() != null) {
  68 + return handleException(dispatchEx.getCause());
  69 + } else {
  70 + return Message.failure(
  71 + ErrorCode.UNKNOWN_ERROR.getCode(), ErrorCode.UNKNOWN_ERROR.getName());
  72 + }
  73 + } else if (ex instanceof ResponseStatusException) {
  74 + ResponseStatusException statusException = (ResponseStatusException) ex;
  75 + log.warn("response status error:{}", statusException.getMessage());
  76 + return Message.failure(statusException.getStatus().value(), ex.getMessage());
  77 + } else if (ex instanceof GatewayParamNotValidException) {
  78 + return Message.failure(
  79 + ErrorCode.ILLEGAL_PARAMS.getCode(), ex.getMessage());
  80 + } else {
  81 + log.error("unknown error:", ex);
  82 + return Message.failure(
  83 + ErrorCode.UNKNOWN_ERROR.getCode(), ErrorCode.UNKNOWN_ERROR.getName());
  84 + }
42 85 }
43 86  
44 87  
... ... @@ -51,10 +94,6 @@ public class FacadeWebFilter implements WebFilter {
51 94 intervalTime,
52 95 exchange.getRequest().getHeaders(),
53 96 JsonUtils.toJsonString(apiMetricsInfo));
54   - if (//apiMetricsInfo.getCode() == ErrorCode.UNKNOWN_ERROR.getCode()&&
55   - apiMetricsInfo.getThrowable() != null) {
56   - log.error("error:", apiMetricsInfo.getThrowable());
57   - }
58 97 }
59 98 }
60 99  
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/route/impl/CloudRouteResourceLoader.java
... ... @@ -9,7 +9,6 @@ import com.diligrp.xtrade.core.route.DynamicRouteLoaderIntf;
9 9 import org.slf4j.Logger;
10 10 import org.slf4j.LoggerFactory;
11 11 import org.springframework.beans.factory.annotation.Autowired;
12   -import org.springframework.beans.factory.annotation.Value;
13 12 import org.springframework.cloud.gateway.config.GatewayProperties;
14 13 import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
15 14 import org.springframework.cloud.gateway.route.RouteDefinition;
... ... @@ -41,12 +40,6 @@ public class CloudRouteResourceLoader implements DynamicRouteLoaderIntf {
41 40 private final static String GROUP = "DEFAULT_GROUP";
42 41 private final static String ROUTE_CONFIG_NAME = "route.properties";
43 42  
44   - @Value("${spring.application.name}")
45   - private String applicationName;
46   - @Value("${spring.profiles.active}")
47   - private String activeProfile;
48   - @Value("${spring.cloud.nacos.config.file-extension}")
49   - private String fileType;
50 43 @Autowired
51 44 private ApplicationContext applicationContext;
52 45 @Resource
... ... @@ -83,8 +76,6 @@ public class CloudRouteResourceLoader implements DynamicRouteLoaderIntf {
83 76 * @date 2020/4/10
84 77 */
85 78 private void loadRoutes() {
86   - //只有放到标准的配置文件下,才能够成功刷新配置
87   - String configFile = String.format("%s-%s.%s", applicationName, activeProfile, fileType);
88 79 try {
89 80 configService.getConfigAndSignListener(
90 81 ROUTE_CONFIG_NAME,
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/support/ApiMetricsCollector.java
... ... @@ -40,7 +40,7 @@ public class ApiMetricsCollector {
40 40 startCollectMetrics();
41 41 }
42 42 };
43   - timer.schedule(task, 1000 * 5);
  43 + timer.schedule(task, 1000 * 15);
44 44 }
45 45  
46 46 private void startCollectMetrics() {
... ...
gateway-core/src/main/java/com/diligrp/xtrade/core/support/dispatch/MappingRegister.java
... ... @@ -77,7 +77,7 @@ public class MappingRegister implements ApplicationListener&lt;ContextRefreshedEven
77 77 log.info("register aggregation mapping 【{}】", uri);
78 78 }
79 79 } catch (Exception e) {
80   - log.error("register mappingMetaInfo error:",e);
  80 + log.error("register mappingMetaInfo error:", e);
81 81 //发生异常直接退出,防止后续无法调用服务
82 82 int exit = SpringApplication.exit(applicationContext, () -> 0);
83 83 System.exit(exit);
... ... @@ -95,12 +95,12 @@ public class MappingRegister implements ApplicationListener&lt;ContextRefreshedEven
95 95 return null;
96 96 }
97 97  
98   - private static Validated getValidateAnnotation(Method method){
  98 + private static Validated getValidateAnnotation(Method method) {
99 99 Annotation[][] parameterAnnotations = method.getParameterAnnotations();
100 100 for (Annotation[] parameterAnnotation : parameterAnnotations) {
101 101 for (Annotation annotation : parameterAnnotation) {
102   - if (Validated.class == annotation.annotationType()){
103   - return (Validated)annotation;
  102 + if (Validated.class == annotation.annotationType()) {
  103 + return (Validated) annotation;
104 104 }
105 105 }
106 106 }
... ...
... ... @@ -27,10 +27,6 @@
27 27 <gateway.version>1.0.0</gateway.version>
28 28 </properties>
29 29 <dependencies>
30   - <dependency>
31   - <groupId>org.springframework.boot</groupId>
32   - <artifactId>spring-boot-configuration-processor</artifactId>
33   - </dependency>
34 30 <!-- <dependency>
35 31 <groupId>org.springframework.boot</groupId>
36 32 <artifactId>spring-boot-starter-cache</artifactId>
... ... @@ -120,4 +116,10 @@
120 116 </plugins>
121 117 </build>
122 118  
  119 + <repositories>
  120 + <repository>
  121 + <id>aliyunmaven</id>
  122 + <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
  123 + </repository>
  124 + </repositories>
123 125 </project>
... ...