|
@@ -0,0 +1,116 @@
|
|
|
+package com.hwrj.cloud.gateway.config;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
|
|
|
+import org.springframework.http.HttpStatus;
|
|
|
+import org.springframework.http.MediaType;
|
|
|
+import org.springframework.http.codec.HttpMessageReader;
|
|
|
+import org.springframework.http.codec.HttpMessageWriter;
|
|
|
+import org.springframework.http.server.reactive.ServerHttpRequest;
|
|
|
+import org.springframework.util.Assert;
|
|
|
+import org.springframework.web.reactive.function.BodyInserters;
|
|
|
+import org.springframework.web.reactive.function.server.RequestPredicates;
|
|
|
+import org.springframework.web.reactive.function.server.RouterFunctions;
|
|
|
+import org.springframework.web.reactive.function.server.ServerRequest;
|
|
|
+import org.springframework.web.reactive.function.server.ServerResponse;
|
|
|
+import org.springframework.web.reactive.result.view.ViewResolver;
|
|
|
+import org.springframework.web.server.ServerWebExchange;
|
|
|
+import reactor.core.publisher.Mono;
|
|
|
+
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @Deacription TODO
|
|
|
+ * @Author jianhua.hong
|
|
|
+ * @Date 2020/4/2 10:36
|
|
|
+ **/
|
|
|
+@Slf4j
|
|
|
+public class GatewayExceptionHandler extends AbstractExceptionHandler implements ErrorWebExceptionHandler {
|
|
|
+
|
|
|
+ private static final String TRACE_ID = "traceId";
|
|
|
+
|
|
|
+ private static final String JHJCN_BUSI_NOT_FOUND = "Unable to find instance for jhjcn-business";
|
|
|
+
|
|
|
+ private static final String JHJCN_BUSI_NOT_FOUND_ZH = "未xxx微服务,请检查服务是否可用";
|
|
|
+
|
|
|
+ private List<HttpMessageReader<?>> messageReaders = Collections.emptyList();
|
|
|
+
|
|
|
+
|
|
|
+ private List<HttpMessageWriter<?>> messageWriters = Collections.emptyList();
|
|
|
+
|
|
|
+
|
|
|
+ private List<ViewResolver> viewResolvers = Collections.emptyList();
|
|
|
+
|
|
|
+
|
|
|
+ private ThreadLocal<Map<String, Object>> exceptionHandlerResult = new ThreadLocal<>();
|
|
|
+
|
|
|
+
|
|
|
+ public void setMessageReaders(List<HttpMessageReader<?>> messageReaders) {
|
|
|
+ Assert.notNull(messageReaders, "'messageReaders' must not be null");
|
|
|
+ this.messageReaders = messageReaders;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void setViewResolvers(List<ViewResolver> viewResolvers) {
|
|
|
+ this.viewResolvers = viewResolvers;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void setMessageWriters(List<HttpMessageWriter<?>> messageWriters) {
|
|
|
+ Assert.notNull(messageWriters, "'messageWriters' must not be null");
|
|
|
+ this.messageWriters = messageWriters;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
|
|
|
+ String errorMessage = super.formatMessage(ex);
|
|
|
+ if (errorMessage.equals(JHJCN_BUSI_NOT_FOUND)) {
|
|
|
+ errorMessage = JHJCN_BUSI_NOT_FOUND_ZH;
|
|
|
+ }
|
|
|
+ Map<String, Object> errorMap = super.buildErrorMap(errorMessage);
|
|
|
+ ServerHttpRequest request = exchange.getRequest();
|
|
|
+ String traceId = request.getHeaders().getFirst(TRACE_ID);
|
|
|
+ log.error("GatewayExceptionHandler request info [traceId={}] result error=[{}]", traceId, JSONObject.toJSONString(errorMap));
|
|
|
+ if (exchange.getResponse().isCommitted()) {
|
|
|
+ return Mono.error(ex);
|
|
|
+ }
|
|
|
+ exceptionHandlerResult.set(errorMap);
|
|
|
+ ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders);
|
|
|
+ return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest)
|
|
|
+ .switchIfEmpty(Mono.error(ex))
|
|
|
+ .flatMap((handler) -> handler.handle(newRequest))
|
|
|
+ .flatMap((response) -> write(exchange, response));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) {
|
|
|
+ Map<String, Object> result = exceptionHandlerResult.get();
|
|
|
+ return ServerResponse.status(HttpStatus.OK)
|
|
|
+ .contentType(MediaType.APPLICATION_JSON_UTF8)
|
|
|
+ .body(BodyInserters.fromObject(result));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private Mono<? extends Void> write(ServerWebExchange exchange,
|
|
|
+ ServerResponse response) {
|
|
|
+ exchange.getResponse().getHeaders()
|
|
|
+ .setContentType(response.headers().getContentType());
|
|
|
+ return response.writeTo(exchange, new ResponseContext());
|
|
|
+ }
|
|
|
+
|
|
|
+ private class ResponseContext implements ServerResponse.Context {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<HttpMessageWriter<?>> messageWriters() {
|
|
|
+ return GatewayExceptionHandler.this.messageWriters;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ViewResolver> viewResolvers() {
|
|
|
+ return GatewayExceptionHandler.this.viewResolvers;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|