Commit 45276d37972c268140c2d40274697ca8d628f88b
1 parent
98f0de9f
优化异常处理
Showing
15 changed files
with
272 additions
and
246 deletions
gateway-business/pom.xml
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
gateway-core/src/main/java/com/diligrp/xtrade/core/support/dispatch/MappingRegister.java
... | ... | @@ -77,7 +77,7 @@ public class MappingRegister implements ApplicationListener<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<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 | } | ... | ... |
pom.xml
... | ... | @@ -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> | ... | ... |