gateway自定义全局异常

一、实现背景:

在前后端分离的浪潮下,发现在实现springcloud gateway时,其默认返回的是字符串,这显示与返回的json结构格格不入。因此为了对gateway默认的反馈异常做了改造

二、整体思路:

通过gateway源码发现,其错误顶级接口为WebExceptionHandler,其实现如下:

其中DefaultErrorWebExceptionHandler为最底层的实现类,如果所有实现就重新来完成,这事一个不小的工程,如果自定义一个类,让其实现继承DefaultErrorWebExceptionHandler,然后重写里面的关键方法(getRoutingFunction、renderErrorResponse),这个不为一个好的选择

三、代码实现:

1. pom添加依赖

<!--spring-cloud-starter-gateway 网关依赖 -->

<dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-gateway</artifactId>

</dependency>

2.编写代码

自定义异常类:

package com.charlie.cloudgataway.common.error;

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.MediaType;

import org.springframework.web.reactive.function.BodyInserters;

import org.springframework.web.reactive.function.server.*;

import reactor.core.publisher.Mono;

import java.util.HashMap;

import java.util.Map;

/**

* @Author: charlie

* @CreateTime: 2022/2/13

* Description: 自定义异常返回信息

*/

public class MyErrorWebExceptionHandler extends DefaultErrorWebExceptionHandler {

        public MyErrorWebExceptionHandler(ErrorAttributes errorAttributes,ResourceProperties                 resourceProperties,ErrorProperties errorProperties,ApplicationContext applicationContext) {

            super(errorAttributes, resourceProperties, errorProperties, applicationContext);

        }

/**

    * 指定响应处理方法为Json处理的方法

    * @param errorAttributes

    * @return

*/

    @Override

    protected RouterFunctiongetRoutingFunction(ErrorAttributes errorAttributes) {

        return RouterFunctions.route(RequestPredicates.all(),this::renderErrorResponse);

    }

/**

    * 重写 renderErrorResponse,自定义响应数据

    * @param request 请求参数

    * @return

*/

    @Override

    protected MonorenderErrorResponse(ServerRequest request) {

        Throwable throwable =super.getError(request);

        Maperror =this.getErrorAttributes(request,this.getErrorAttributeOptions(request,MediaType.ALL));

        return ServerResponse.status(this.getHttpStatus(error)).

                    contentType(MediaType.APPLICATION_JSON).

                    body(BodyInserters.fromValue(this.response(this.getHttpStatus(error),this.bulidMessage(request,thr                            owable))));

    }

/**

    * 根据Code获取对应的HttpStatus

    * @param errorAttributes

    * @return

*/

    @Override

    protected int getHttpStatus(Map errorAttributes) {

        return (Integer)errorAttributes.get("status");

    }

/**

    * 构建异常信息

    * @param request

    * @param ex

    * @return

*/

    private String bulidMessage(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

*/

private 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);

        return map;

    }

}

自定义配置类:

package com.charlie.cloudgataway.config;

import com.charlie.cloudgataway.common.error.MyErrorWebExceptionHandler;

import org.springframework.beans.factory.ObjectProvider;

import org.springframework.boot.autoconfigure.web.ResourceProperties;

import org.springframework.boot.autoconfigure.web.ServerProperties;

import org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler;

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;

/**

* @Author: charlie

* @CreateTime: 2022/2/13

* Description: Gateway异常配置类

*/

@Configuration

public class GatewayConfig {

    private final ServerProperties serverProperties;

    private final ApplicationContext applicationContext;

    private  final ResourceProperties resourceProperties;

    private final List<ViewResolver> viewResolvers;

    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfig(ServerProperties serverProperties, ApplicationContext applicationContext,                              ResourceProperties resourceProperties,  

                    ObjectProvider<List<ViewResolver>>    viewResolverProvider, 

                    ServerCodecConfigurer serverCodecConfigurer) {

        this.serverProperties  = serverProperties;

        this.applicationContext = applicationContext;

        this.resourceProperties = resourceProperties;

        this.viewResolvers = viewResolverProvider.getIfAvailable(Collections::emptyList);

        this.serverCodecConfigurer = serverCodecConfigurer;

    }

    @Bean("myErrorWebExceptionHandler")

    @Order(Ordered.HIGHEST_PRECEDENCE)

    public ErrorWebExceptionHandler myErrorWebExceptionHandler(ErrorAttributes errorAttributes) {

        DefaultErrorWebExceptionHandler exceptionHandler = new MyErrorWebExceptionHandler(errorAttributes,

                this.resourceProperties,this.serverProperties.getError(),this.applicationContext);

        exceptionHandler.setViewResolvers(this.viewResolvers);

        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());

        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());

        return exceptionHandler;

    }

}

四、效果对比:

1.重写前  异常访问返回结果


2.重写后  异常访问返回结果


以上的代码是通过本人运行,希望对看到的您有所帮助!对应异常返回的内容及格式,可以参考以上思考实现自定义

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容