通常spring boot全局异常捕获我们通常会使用@ControllerAdvice进行全局捕获。放到网关中显然不合适,@ControllerAdvice故名思意,是对controller的一个增强处理。所以在gateway中我们需要如下方式配置: 
网关全局异常配置
 
@Configuration
@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
public class ExceptionConfig {
    private final ServerProperties serverProperties;
    private final ApplicationContext applicationContext;
    private final ResourceProperties resourceProperties;
    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;
    public ExceptionConfig(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) {
        ExceptionHandler exceptionHandler = new ExceptionHandler(
                errorAttributes,
                this.resourceProperties,
                this.serverProperties.getError(),
                this.applicationContext);
        exceptionHandler.setViewResolvers(this.viewResolvers);
        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
        return exceptionHandler;
    }
}
 
网关全局异常处理类
 
对异常返回结果的处理,注意:如果我们对返回的结果进行了加密处理的话,前端接收参数肯定时统一对数据进行解密。所以我们返回的异常信息同样需要加密操作。如果未进行加密处理,则此处无需进行处理。(详细见ExceptionHandler类 response方法) 
public class ExceptionHandler extends DefaultErrorWebExceptionHandler {
    public ExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
                            ErrorProperties errorProperties, ApplicationContext applicationContext) {
        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
    }
    
    @Override
    protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
        String bgDebug = request.exchange().getAttributeOrDefault(ConstantFilter.BG_DEBUG_KEY, ConstantFilter.REQ_RES_ENCRYPT);
        int code = 500;
        Throwable error = super.getError(request);
        if (error instanceof org.springframework.cloud.gateway.support.NotFoundException) {
            code = 404;
        }
        return response(bgDebug, code, error.getMessage());
    }
    
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }
    
    @Override
    protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) {
        int statusCode = 500;
        Object code = errorAttributes.get("code");
        if(code != null){
            statusCode = (int) code;
        }
        return HttpStatus.valueOf(statusCode);
    }
    
    private static JSONObject response(String bgDebug, int status, String errorMessage) {
        R r = R.error(status, errorMessage);
        if(ConstantFilter.REQ_RES_ENCRYPT.equals(bgDebug)){
            
            String randomKey = AESUtil.getRandomKey();
            String encryptData = AESUtil.AESEncrypt(JSONObject.toJSONString(r), randomKey, "CBC");
            String encryptRandomKey = RSAUtils.publicEncrypt(randomKey);
            JSONObject json = new JSONObject();
            json.put("k", encryptRandomKey);
            json.put("v", encryptData);
            return json;
        } else {
            
            JSONObject json = new JSONObject();
            json.put("code", status);
            json.put("msg", errorMessage);
            return json;
        }
    }
}
                
                
                
        
    
转载请注明原文地址:https://blackberry.8miu.com/read-2639.html