之前前端直接访问后端微服务的Controller接口,如果抛出异常,会自动被编写的全局异常处理器(@ControllerAdvice )捕获返回一个正常的响应,响应的R对象中描述错误信息
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public R exception(Exception e) {
log.info("异常信息==>>\n" + ExceptionUtils.getStackTrace(e));
log.warn("异常类型==>>\n" + e.getClass().getName(), new Date());
return R.error();
现在网关项目的异常没有被处理,直接抛给前端,前端就会出现5xx的服务器错误.
例如:
503:
网关接受到请求时,路由断言成功,可以匹配到路由中的一个微服务的配置
但是网关再注册中心中找不到目标微服务,则报错503
解决方案:
配置网关全局异常处理
- 创建自定义异常处理类GlobalJsonExceptionHandler
package com.atlin.guli.infrastructure.apigateway.exception;
import com.atlin.guli.service.base.result.ResultCodeEnum;
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.cloud.gateway.support.NotFoundException;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.reactive.function.server.*;
import java.util.HashMap;
import java.util.Map;
* note_Spring Cloud Gateway 底层使用的WebFlux,全局异常处理不能直接使用 @ControllerAdvice,
* 可以通过继承DefaultErrorWebExceptionHandler实现自定义异常处理:
* @author lin
* @version v1.0
* @description 自定义 网关全局json异常处理/ 自定义异常处理类GlobalJsonExceptionHandler
public class GlobalJsonExceptionHandler extends DefaultErrorWebExceptionHandler {
* 1、指定使用json格式进行响应
* @param errorAttributes
* @return
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
* 2、提供异常数据 : 响应报文数据
* @param request request
* @param includeStackTrace includeStackTrace
* @return
@Override
protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
Map<String, Object> map = new HashMap<>();
map.put("code", 500);
Throwable error = getError(request);
if (error instanceof NotFoundException) {
map.put("code", 404);
map.put("message", error.getMessage());
Map<String, Object> rMap = new HashMap<>();
rMap.put("code", ResultCodeEnum.API_GATEWAY_GLOBAL_ERROR.getCode());
rMap.put("success", ResultCodeEnum.API_GATEWAY_GLOBAL_ERROR.getSuccess());
rMap.put("message", ResultCodeEnum.API_GATEWAY_GLOBAL_ERROR.getMessage());
map.put("data", rMap);
return map;
* 3、提供响应报文的状态码
* @param errorAttributes
* @return
@Override
protected int getHttpStatus(Map<String, Object> errorAttributes) {
int code = (int) errorAttributes.get("code");
return HttpStatus.valueOf(code).value();
public GlobalJsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties, ErrorProperties errorProperties, ApplicationContext applicationContext) {
super(errorAttributes, resourceProperties, errorProperties, applicationContext);
- 使用自定义异常处理覆盖默认异常处理
* 将bean注入到容器中的方式:
* 1、xml配置文件bean标签
* 2、组件注解
* 3、组件类中通过@Bean标注的方法返回值
@Bean
public DefaultErrorWebExceptionHandler defaultErrorWebExceptionHandler(
ErrorAttributes errorAttributes,
org.springframework.boot.autoconfigure.web.ResourceProperties resourceProperties,
ServerProperties serverProperties,
ObjectProvider<ViewResolver> viewResolvers,
ServerCodecConfigurer serverCodecConfigurer,
ApplicationContext applicationContext
GlobalJsonExceptionHandler exceptionHandler = new GlobalJsonExceptionHandler(
errorAttributes,
resourceProperties,
serverProperties.getError(),
applicationContext);
exceptionHandler.setViewResolvers(viewResolvers.orderedStream().collect(Collectors.toList()));
exceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters());
exceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders());
return exceptionHandler;
Spring Cloud Gateway 全局通用异常处理
在传统 Spring Boot 应用中, 我们 @ControllerAdvice 来处理全局的异常,进行统一包装返回
// 摘至 spring cloud alibaba console 模块处理
@ControllerAdvice
public class ConsoleExceptionHandler {
@ExceptionHandler(AccessException.class)
private ResponseE
在全局过滤器中可以处理网络异常请求,但是当设置Gateway请求超时时间,超时后的异常全局过滤器中处理不了。
定义CustomWebExceptionHandler类
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.tigerkin.util.ApiResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springfr
Spring Cloud Gateway中的全局异常处理不能直接用@ControllerAdvice来处理,通过跟踪异常信息的抛出,找到对应的源码,自定义一些处理逻辑来符合业务的需求。
网关都是给接口做代理转发的,后端对应的都是REST API,返回数据格式都是JSON。如果不做处理,当发生异常时,Gateway默认给出的错误信息是页面,不方便前端进行异常处理。
需要对异常信息进行处理,返回JSO...
对于spring boot 项目 全局异常拦截可以使用@RestControllerAdvice 和@ExceptionHandler(Exception.class) 注解 进行全局异常处理。对于Gateway 内部的异常处理需要使用如下方法
package config.exception;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure..
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ResourceProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.Defa
Gateway网关统一全局异常处理操作 方便前端看到 这里要精细化翻译,默认返回用户是看不懂的 所以需要配置一个 Gateway 的全局异常处理器如果没有网关全局异常的 会如下截图以上就是今天要讲的内容,本文仅仅简单 所以需要配置一个 Gateway 的全局异常处理器。
GateWay网关全局异常处理@RestControllerAdvice 失效问题
GateWay网关全局异常处理@RestControllerAdvice 失效问题
因项目中用到了@RestControllerAdvice处理http各种状态码异常
使用postman测试发现模拟状态码异常,发现不起作用。
后来发现我引用的jar包实现了 AbstractErrorWebExceptionHandler接口,参考:https://docs.spring.io/spring-boot/docs/curre
我的项目中,使用spring cloud gateway作为路由,根据路由规则访问不同的api,api中使用的是fegin,当api未启动或者出现异常时候,会返回以下的异常信息
而正常的情况我们接口返回的数据是经过封装的,所以我们需要将这里的异常也进行处理,使其数据格式与我们接口中保持一致,方便前端进行统一处理。
获取及重新捕获异常的代码:
import org.springframework....
/*** @version 2019/8/14* @description: 异常拦截器* @modified:*/@Slf4jpublic class JsonExceptionHandler implements ErrorWebExceptionHandler {/*** MessageReader*/private List> messageReaders = Collections...