首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring Cloud Gateway全局异常处理和自定义错误响应

Spring Cloud Gateway全局异常处理和自定义错误响应
EN

Stack Overflow用户
提问于 2021-02-18 14:10:30
回答 1查看 250关注 0票数 0

我有一个自定义的过滤器,在使用Spring Cloud Gateway调用实际API之前,它会对每个请求进行身份验证。在Spring Cloud中有没有办法像Spring provide @ControllerAdvice那样集中处理异常呢?我希望全局处理异常,并从网关返回自定义错误响应。

EN

回答 1

Stack Overflow用户

发布于 2021-08-17 10:57:15

一旦从身份验证筛选器引发异常,就可以通过重写DefaultErrorAttributes类来自定义错误响应。

代码语言:javascript
复制
@Component
public class GlobalErrorAttributes extends DefaultErrorAttributes {


    private static final Logger logger = LoggerFactory.getLogger(GlobalErrorAttributes.class);

    public GlobalErrorAttributes() {
    }

    public GlobalErrorAttributes(boolean includeException) {
        super(includeException);
    }

    @Override
    public Map<String, Object> getErrorAttributes(ServerRequest request,
                                                  boolean includeStackTrace) {
        Throwable error = this.getError(request);
        logger.error("Error occured", error);
        MergedAnnotation<ResponseStatus> responseStatusAnnotation = MergedAnnotations
                .from(error.getClass(), MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).get(ResponseStatus.class);
        HttpStatus errorStatus = findHttpStatus(error, responseStatusAnnotation);
        logger.info("errorStatus: {}", errorStatus);
        Map<String, Object> map = super.getErrorAttributes(request, includeStackTrace);
        String errorCode = getErrorCode(map, errorStatus);
        map.remove("timestamp");
        map.remove("path");
        map.remove("error");
        map.remove("requestId");
        map.put("errorCode", errorCode);
        return map;
    }

    private HttpStatus findHttpStatus(Throwable error, MergedAnnotation<ResponseStatus> responseStatusAnnotation) {
        if (error instanceof ResponseStatusException) {
            return ((ResponseStatusException) error).getStatus();
        }
        return responseStatusAnnotation.getValue("code", HttpStatus.class).orElse(INTERNAL_SERVER_ERROR);
    }

    private String getErrorCode(Map<String, Object> map, HttpStatus errorStatus) {
        String errorCode;
        switch (errorStatus) {
            case UNAUTHORIZED:
                errorCode = "401 UnAuthorized";
                break;
            case NOT_FOUND:
                logger.error("The url:{} is not found", map.get("path"));
                errorCode = "404 Not Found";
                map.put(MESSAGE, "NOT FOUND");
                break;
            case METHOD_NOT_ALLOWED:
                logger.error("Invalid HTTP Method type for the url: {}", map.get("path"));
                errorCode = "405 Method Not Allowed";
                break;
            default:
                logger.error("Unexpected error happened");
                logger.error("errorstatus is : {}", errorStatus);
                errorCode = "500 Internal Server Error";
                map.put(MESSAGE, "Unexpected Error");
        }
        return errorCode;
    }
}

输出将如下所示:

代码语言:javascript
复制
{
   "status": 401,
   "message": "Invalid Access Token",
   "error_code": "401 UnAuthorized"
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66254535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档