在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里面处理全局异常的代码,直接抄到项目里面就可以使用。











还没有评论,来说两句吧...