概述
之前前端直接访问后端微服务的Controller接口,如果抛出异常,会自动被编写的全局异常处理器(@ControllerAdvice )捕获返回一个正常的响应,响应的R对象中描述错误信息
@Slf4j//lombok的注解,springboot项目底层默认引入slf4j日志门面+logback日志框架,动态提供
@RestControllerAdvice
//@ControllerAdvice//返回值不会处理为json
public class GlobalExceptionHandler {
//当Controller抛出异常时,没有被其他ExceptionHandler处理的时候,会被此handler捕获
@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) {
//参数1:匹配所有的请求(所有出现异常的请求) 参数2:指定自己设置响应(默认转为json)
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) {
// 响应报文的参数:code message data 如果需要设置R对象:我们需要封装R对象的属性设置到data属性中
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<>();//R对象
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) {
// 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
// @Order(-1) //设置优先级
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;
}
最后
以上就是感性啤酒为你收集整理的【SpringCloud】Spring Cloud Gateway 网关全局异常处理的全部内容,希望文章能够帮你解决【SpringCloud】Spring Cloud Gateway 网关全局异常处理所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复