Browse Source

网关异常处理

by su 3 years ago
parent
commit
e42c9f068d

+ 1 - 1
4dkankan-center-scene/src/main/java/com/fdkankan/scene/SceneApplication.java

@@ -22,7 +22,7 @@ public class SceneApplication {
         System.out.println("进入了");
         int i = 1;
         StrExtUtil.isNotBlank("123");
-        i = i/0;
+        int i1 = i / 0;
         return test;
     }
 

+ 6 - 1
4dkankan-center-scene/src/main/java/com/fdkankan/scene/dto/TestDto.java

@@ -1,10 +1,15 @@
 package com.fdkankan.scene.dto;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
+@NoArgsConstructor
 @Data
 public class TestDto {
 
-    private int id;
+    @JsonProperty("id")
+    private Integer id;
+    @JsonProperty("name")
     private String name;
 }

+ 25 - 0
4dkankan-common/src/main/java/com/fdkankan/common/constant/ServerCode.java

@@ -0,0 +1,25 @@
+package com.fdkankan.common.constant;
+
+public enum ServerCode {
+
+	SUCCESS(0, "成功"),
+	SYSTEM_ERROR(-1, "服务器异常"),
+	PARAM_ERROR(-2, "解析请求参数出错"),
+	;
+	
+	private Integer code;
+	private String message;
+
+	private ServerCode(Integer code, String message) {
+		this.code = code;
+		this.message = message;
+	}
+
+	public Integer code() {
+		return code;
+	}
+
+	public String message() {
+		return message;
+	}
+}

+ 80 - 0
4dkankan-gateway/src/main/java/com/fdkankan/gateway/config/CustomErrorWebFluxAutoConfiguration.java

@@ -0,0 +1,80 @@
+package com.fdkankan.gateway.config;
+
+import com.fdkankan.gateway.exception.JsonErrorWebExceptionHandler;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.autoconfigure.condition.SearchStrategy;
+import org.springframework.boot.autoconfigure.web.ResourceProperties;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
+import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
+import org.springframework.boot.web.reactive.error.ErrorAttributes;
+import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.codec.ServerCodecConfigurer;
+import org.springframework.web.reactive.config.WebFluxConfigurer;
+import org.springframework.web.reactive.result.view.ViewResolver;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Configuration
+@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
+@ConditionalOnClass(WebFluxConfigurer.class)
+@AutoConfigureBefore(WebFluxAutoConfiguration.class)
+@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
+public class CustomErrorWebFluxAutoConfiguration {
+
+    private final ServerProperties serverProperties;
+
+    private final ApplicationContext applicationContext;
+
+    private final ResourceProperties resourceProperties;
+
+    private final List<ViewResolver> viewResolvers;
+
+    private final ServerCodecConfigurer serverCodecConfigurer;
+
+    public CustomErrorWebFluxAutoConfiguration(ServerProperties serverProperties,
+                                               ResourceProperties resourceProperties,
+                                               ObjectProvider<ViewResolver> viewResolversProvider,
+                                               ServerCodecConfigurer serverCodecConfigurer,
+                                               ApplicationContext applicationContext) {
+        this.serverProperties = serverProperties;
+        this.applicationContext = applicationContext;
+        this.resourceProperties = resourceProperties;
+        this.viewResolvers = viewResolversProvider.orderedStream()
+                .collect(Collectors.toList());
+        this.serverCodecConfigurer = serverCodecConfigurer;
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(value = ErrorWebExceptionHandler.class,
+            search = SearchStrategy.CURRENT)
+    @Order(-1)
+    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
+        // TODO 这里完成自定义ErrorWebExceptionHandler实现逻辑
+        JsonErrorWebExceptionHandler exceptionHandler = new JsonErrorWebExceptionHandler(
+                errorAttributes,
+                resourceProperties,
+                this.serverProperties.getError(),
+                applicationContext);
+        exceptionHandler.setViewResolvers(this.viewResolvers);
+        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
+        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
+        return exceptionHandler;
+    }
+
+    @Bean
+    @ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
+    public DefaultErrorAttributes errorAttributes() {
+        return new DefaultErrorAttributes(this.serverProperties.getError().isIncludeException());
+    }
+}

+ 0 - 60
4dkankan-gateway/src/main/java/com/fdkankan/gateway/config/ExceptionHandlerConfiguration.java

@@ -1,60 +0,0 @@
-//package com.fdkankan.gateway.config;
-//
-//import com.fdkankan.gateway.exception.JsonExceptionHandler;
-//import org.springframework.beans.factory.ObjectProvider;
-//import org.springframework.boot.autoconfigure.web.ResourceProperties;
-//import org.springframework.boot.autoconfigure.web.ServerProperties;
-//import org.springframework.boot.context.properties.EnableConfigurationProperties;
-//import org.springframework.boot.web.reactive.error.ErrorAttributes;
-//import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
-//import org.springframework.context.ApplicationContext;
-//import org.springframework.context.annotation.Bean;
-//import org.springframework.context.annotation.Configuration;
-//import org.springframework.core.Ordered;
-//import org.springframework.core.annotation.Order;
-//import org.springframework.http.codec.ServerCodecConfigurer;
-//import org.springframework.web.reactive.result.view.ViewResolver;
-//
-//import java.util.Collections;
-//import java.util.List;
-//
-//@Configuration
-//@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
-//public class ExceptionHandlerConfiguration {
-//
-//    private final ServerProperties serverProperties;
-//
-//    private final ApplicationContext applicationContext;
-//
-//    private final ResourceProperties resourceProperties;
-//
-//    private final List<ViewResolver> viewResolvers;
-//
-//    private final ServerCodecConfigurer serverCodecConfigurer;
-//
-//    public ExceptionHandlerConfiguration(ServerProperties serverProperties,
-//                                         ResourceProperties resourceProperties,
-//                                         ObjectProvider<List<ViewResolver>> viewResolversProvider,
-//                                         ServerCodecConfigurer serverCodecConfigurer,
-//                                         ApplicationContext applicationContext) {
-//        this.serverProperties = serverProperties;
-//        this.applicationContext = applicationContext;
-//        this.resourceProperties = resourceProperties;
-//        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
-//        this.serverCodecConfigurer = serverCodecConfigurer;
-//    }
-//
-//    @Bean
-//    @Order(Ordered.HIGHEST_PRECEDENCE)
-//    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
-//        JsonExceptionHandler exceptionHandler = new JsonExceptionHandler(
-//                errorAttributes,
-//                this.resourceProperties,
-//                this.serverProperties.getError(),
-//                this.applicationContext);
-//        exceptionHandler.setViewResolvers(this.viewResolvers);
-//        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
-//        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
-//        return exceptionHandler;
-//    }
-//}

+ 57 - 53
4dkankan-gateway/src/main/java/com/fdkankan/gateway/exception/GlobalErrorWebExceptionHandler.java

@@ -1,53 +1,57 @@
-package com.fdkankan.gateway.exception;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fdkankan.common.response.ResultData;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.Order;
-import org.springframework.core.io.buffer.DataBufferFactory;
-import org.springframework.http.MediaType;
-import org.springframework.http.server.reactive.ServerHttpResponse;
-import org.springframework.web.server.ResponseStatusException;
-import org.springframework.web.server.ServerWebExchange;
-import reactor.core.publisher.Mono;
-
-@Slf4j
-@Order(-1)
-@Configuration
-@RequiredArgsConstructor(onConstructor = @__(@Autowired))
-public class GlobalErrorWebExceptionHandler implements ErrorWebExceptionHandler {
-
-    private final ObjectMapper objectMapper;
-
-    @Override
-    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
-        ServerHttpResponse response = exchange.getResponse();
-        if (response.isCommitted()) {
-            return Mono.error(ex);
-        }
-
-        // 设置返回JSON
-        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
-
-        if (ex instanceof ResponseStatusException) {
-            response.setStatusCode(((ResponseStatusException) ex).getStatus());
-        }
-
-        return response.writeWith(Mono.fromSupplier(() -> {
-            DataBufferFactory bufferFactory = response.bufferFactory();
-            try {
-                //返回响应结果
-                return bufferFactory.wrap(objectMapper.writeValueAsBytes(ResultData.fail(500,ex.getMessage())));
-            }
-            catch (JsonProcessingException e) {
-                log.error("Error writing response", ex);
-                return bufferFactory.wrap(new byte[0]);
-            }
-        }));
-    }
-}
+//package com.fdkankan.gateway.exception;
+//
+//import com.fasterxml.jackson.core.JsonProcessingException;
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import com.fdkankan.common.constant.ServerCode;
+//import com.fdkankan.common.response.ResultData;
+//import lombok.RequiredArgsConstructor;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
+//import org.springframework.cloud.gateway.support.NotFoundException;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.core.annotation.Order;
+//import org.springframework.core.io.buffer.DataBufferFactory;
+//import org.springframework.http.MediaType;
+//import org.springframework.http.server.reactive.ServerHttpResponse;
+//import org.springframework.web.server.ResponseStatusException;
+//import org.springframework.web.server.ServerWebExchange;
+//import reactor.core.publisher.Mono;
+//
+//@Slf4j
+//@Order(-1)
+////@Configuration
+//@RequiredArgsConstructor(onConstructor = @__(@Autowired))
+//public class GlobalErrorWebExceptionHandler implements ErrorWebExceptionHandler {
+//
+//    private final ObjectMapper objectMapper;
+//
+//    @Override
+//    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
+//
+//        ServerHttpResponse response = exchange.getResponse();
+//        if (response.isCommitted()) {
+//            return Mono.error(ex);
+//        }
+//
+//        // 设置返回JSON
+//        response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
+//
+//        if (ex instanceof ResponseStatusException) {
+//            response.setStatusCode(((ResponseStatusException) ex).getStatus());
+//        }
+//
+//        return response.writeWith(Mono.fromSupplier(() -> {
+//            DataBufferFactory bufferFactory = response.bufferFactory();
+//            try {
+//                //返回响应结果
+//                log.error(ex.getMessage());
+//                return bufferFactory.wrap(objectMapper.writeValueAsBytes(ResultData.fail(ServerCode.SYSTEM_ERROR.code(), ServerCode.SYSTEM_ERROR.message())));
+//            }
+//            catch (JsonProcessingException e) {
+//                log.error("Error writing response", ex);
+//                return bufferFactory.wrap(new byte[0]);
+//            }
+//        }));
+//    }
+//}

+ 52 - 0
4dkankan-gateway/src/main/java/com/fdkankan/gateway/exception/JsonErrorWebExceptionHandler.java

@@ -0,0 +1,52 @@
+package com.fdkankan.gateway.exception;
+
+
+import com.fdkankan.common.constant.ServerCode;
+import org.springframework.boot.autoconfigure.web.ErrorProperties;
+import org.springframework.boot.autoconfigure.web.ResourceProperties;
+import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
+import org.springframework.boot.web.error.ErrorAttributeOptions;
+import org.springframework.boot.web.reactive.error.ErrorAttributes;
+import org.springframework.context.ApplicationContext;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.reactive.function.server.*;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+public class JsonErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler {
+
+    public JsonErrorWebExceptionHandler(ErrorAttributes errorAttributes,
+                                        ResourceProperties resourceProperties,
+                                        ErrorProperties errorProperties,
+                                        ApplicationContext applicationContext) {
+        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
+    }
+
+    @Override
+    protected Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
+        // 这里其实可以根据异常类型进行定制化逻辑
+//        Throwable error = super.getError(request);
+        Map<String, Object> errorAttributes = new HashMap<>(8);
+        errorAttributes.put("status", ServerCode.SYSTEM_ERROR.code());
+        errorAttributes.put("message", ServerCode.SYSTEM_ERROR.message());
+        errorAttributes.put("method", request.methodName());
+        errorAttributes.put("path", request.path());
+        errorAttributes.put("timestamp", Calendar.getInstance().getTimeInMillis());
+        return errorAttributes;
+    }
+
+    @Override
+    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
+        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
+    }
+
+    @Override
+    protected int getHttpStatus(Map<String, Object> errorAttributes) {
+        // 这里其实可以根据errorAttributes里面的属性定制HTTP响应码
+        return HttpStatus.INTERNAL_SERVER_ERROR.value();
+    }
+
+
+}

+ 0 - 89
4dkankan-gateway/src/main/java/com/fdkankan/gateway/exception/JsonExceptionHandler.java

@@ -1,89 +0,0 @@
-//package com.fdkankan.gateway.exception;
-//
-//import lombok.extern.slf4j.Slf4j;
-//import org.springframework.boot.autoconfigure.web.ErrorProperties;
-//import org.springframework.boot.autoconfigure.web.ResourceProperties;
-//import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;
-//import org.springframework.boot.web.reactive.error.ErrorAttributes;
-//import org.springframework.context.ApplicationContext;
-//import org.springframework.http.HttpStatus;
-//import org.springframework.web.reactive.function.server.*;
-//
-//import java.util.HashMap;
-//import java.util.Map;
-//
-//@Slf4j
-//public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {
-//
-//    public JsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
-//                                ErrorProperties errorProperties, ApplicationContext applicationContext) {
-//        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
-//    }
-//
-//    /**
-//     * 获取异常属性
-//     */
-//    @Override
-//    protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
-//        int code = HttpStatus.INTERNAL_SERVER_ERROR.value();
-//        Throwable error = super.getError(request);
-//        if (error instanceof org.springframework.cloud.gateway.support.NotFoundException) {
-//            code = HttpStatus.NOT_FOUND.value();
-//        }
-//        return response(code, this.buildMessage(request, error));
-//    }
-//
-//    /**
-//     * 指定响应处理方法为JSON处理的方法
-//     * @param errorAttributes
-//     */
-//    @Override
-//    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
-//        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
-//    }
-//
-//
-//    /**
-//     * 根据code获取对应的HttpStatus
-//     * @param errorAttributes
-//     */
-//    @Override
-//    protected int getHttpStatus(Map<String, Object> errorAttributes) {
-//        int statusCode = (int) errorAttributes.get("status");
-//        return statusCode;
-//    }
-//
-//    /**
-//     * 构建异常信息
-//     * @param request
-//     * @param ex
-//     * @return
-//     */
-//    private String buildMessage(ServerRequest request, Throwable ex) {
-//        StringBuilder message = new StringBuilder("Failed to handle request [");
-//        message.append(request.methodName());
-//        message.append(" ");
-//        message.append(request.uri());
-//        message.append("]");
-//        if (ex != null) {
-//            message.append(": ");
-//            message.append(ex.getMessage());
-//        }
-//        return message.toString();
-//    }
-//
-//    /**
-//     * 构建返回的JSON数据格式
-//     * @param status        状态码
-//     * @param errorMessage  异常信息
-//     * @return
-//     */
-//    public static Map<String, Object> response(int status, String errorMessage) {
-//        Map<String, Object> map = new HashMap<>();
-//        map.put("code", status);
-//        map.put("message", errorMessage);
-//        map.put("data", null);
-//        log.error(map.toString());
-//        return map;
-//    }
-//}