我们知道在某一个服务中出现异常,可以通过 @ControllerAdvice + @ExceptionHandler 来统一异常处理,即使是在微服务架构中,我们也可以将上述统一异常处理放入到公共的微服务中,这样哪一个微服务需要,直接引入模块即可。 但是如果我们的 网关微服务 出现了异常,该怎么处理呢?
步骤如下:
代码注释如下:
- @Slf4j
- @Configuration
- public class GlobalExceptionConfig implements ErrorWebExceptionHandler {
-
-
- @Autowired
- private ObjectMapper objectMapper;
-
- /**
- * 全局异常处理
- * @param exchange 交换器(request, response)
- * @param ex 出现异常时的异常对象
- * @return
- */
- @Override
- public Mono
handle(ServerWebExchange exchange, Throwable ex) { - Map
result = new HashMap<>(); - //1.获取响应对象
- ServerHttpResponse response = exchange.getResponse();
-
- //2. response 是否结束(一般不用,可以用来处理多个异常的场景)
- if(response.isCommitted()) {
- return Mono.error(ex);
- }
-
- //3.设置响应头类型(JSON)
- response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
-
- //4.设置响应状态码
- if (ex instanceof IllegalTokenException) {
- //是我们自定义的异常
- response.setStatusCode(HttpStatus.FORBIDDEN);
- } else {
- //不是我们自定义的异常,就通过 "服务器异常" 来处理
- response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
- }
-
- //5.处理统一异常响应
- return response.writeWith(Mono.fromSupplier(() -> {
- DataBufferFactory bufferFactory = response.bufferFactory();
- result.put("msg", ex.getMessage());
- try {
- return bufferFactory.wrap(objectMapper.writeValueAsBytes(result));
- } catch (JsonProcessingException e) {
- throw new RuntimeException(e);
- }
- }));
- }
-
- }
那么,如果在网关的中抛出了异常,如下: