在spring cloud 微服务中,我们的业务springboot一般都是一些controller,所以几乎都是基于spring-boot-starter-web来构建的,因此对于全局异常来说,我们只需要一个@RestControllerAdvice的类来处理全局异常就可以了,但是在spring cloud gateway里面,他不是基于spring-boot-starter-web来操作的,而是基于spring-boot-starter-webflux来操作的,因此这里使用@RestControllerAdvice这个注解在spring cloud gateway里面就不起作用了,那么在spring cloud gateway里面我们如何处理全局异常呢?其实非常简单,因此所有的异常都是基于ErrorWebExceptionHandler来处理的,所以我们自定义一个ErrorWebExceptionHandler子类来处理即可,下面是完整的代码:
package org.shop.gateway.server.handler; import org.shop.common.model.http.BaseResponse; 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 com.alibaba.fastjson.JSON; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import reactor.core.publisher.Mono; /** * 网关异常通用处理器,只作用在webflux 环境下 , 优先级低于 {@link ResponseStatusExceptionHandler} 执行 */ @Slf4j @Order(-1) @RequiredArgsConstructor @Configuration public class GlobalExceptionConfiguration implements ErrorWebExceptionHandler { private final ObjectMapper objectMapper; @Override public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { log.info("进入了handle处理"); ServerHttpResponse response = exchange.getResponse(); if (response.isCommitted()) { return Mono.error(ex); } // header set 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 { BaseResponse fail = BaseResponse.fail(ex.getMessage()); log.info("组装错误代码:{}",JSON.toJSONString(fail)); return bufferFactory.wrap(objectMapper.writeValueAsBytes(fail)); } catch (Exception e) { log.warn("Error writing response", ex); return bufferFactory.wrap(new byte[0]); } })); } }
然后我们启动下项目,可以看到原来的错误返回输出是这样子的:
{ "timestamp": "2023-05-06 15:35:01", "path": "/product/hello", "status": 500, "error": "Internal Server Error", "message": "", "requestId": "d48758cf-1" }
如下图:
当我们配置上这个类之后,我们再请求一下,可以看到返回结果变成了:
{ "errorCode": 400, "errorMsg": "token error", "data": null }
如下图:
以上就是在spring cloud gateway里面处理全局异常的代码,直接抄到项目里面就可以使用。
还没有评论,来说两句吧...