通常spring boot全局异常捕获我们通常会使用@ControllerAdvice进行全局捕获。放到网关中显然不合适,@ControllerAdvice故名思意,是对controller的一个增强处理。所以在gateway中我们需要如下方式配置:
网关全局异常配置
@Configuration
@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
public class ExceptionConfig {
private final ServerProperties serverProperties;
private final ApplicationContext applicationContext;
private final ResourceProperties resourceProperties;
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public ExceptionConfig(ServerProperties serverProperties,
ResourceProperties resourceProperties,
ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer,
ApplicationContext applicationContext) {
this.serverProperties = serverProperties;
this.applicationContext = applicationContext;
this.resourceProperties = resourceProperties;
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
ExceptionHandler exceptionHandler = new ExceptionHandler(
errorAttributes,
this.resourceProperties,
this.serverProperties.getError(),
this.applicationContext);
exceptionHandler.setViewResolvers(this.viewResolvers);
exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
return exceptionHandler;
}
}
网关全局异常处理类
对异常返回结果的处理,注意:如果我们对返回的结果进行了加密处理的话,前端接收参数肯定时统一对数据进行解密。所以我们返回的异常信息同样需要加密操作。如果未进行加密处理,则此处无需进行处理。(详细见ExceptionHandler类 response方法)
public class ExceptionHandler extends DefaultErrorWebExceptionHandler {
public ExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
ErrorProperties errorProperties, ApplicationContext applicationContext) {
super(errorAttributes, resourceProperties, errorProperties, applicationContext);
}
@Override
protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
String bgDebug = request.exchange().getAttributeOrDefault(ConstantFilter.BG_DEBUG_KEY, ConstantFilter.REQ_RES_ENCRYPT);
int code = 500;
Throwable error = super.getError(request);
if (error instanceof org.springframework.cloud.gateway.support.NotFoundException) {
code = 404;
}
return response(bgDebug, code, error.getMessage());
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
@Override
protected HttpStatus getHttpStatus(Map<String, Object> errorAttributes) {
int statusCode = 500;
Object code = errorAttributes.get("code");
if(code != null){
statusCode = (int) code;
}
return HttpStatus.valueOf(statusCode);
}
private static JSONObject response(String bgDebug, int status, String errorMessage) {
R r = R.error(status, errorMessage);
if(ConstantFilter.REQ_RES_ENCRYPT.equals(bgDebug)){
String randomKey = AESUtil.getRandomKey();
String encryptData = AESUtil.AESEncrypt(JSONObject.toJSONString(r), randomKey, "CBC");
String encryptRandomKey = RSAUtils.publicEncrypt(randomKey);
JSONObject json = new JSONObject();
json.put("k", encryptRandomKey);
json.put("v", encryptData);
return json;
} else {
JSONObject json = new JSONObject();
json.put("code", status);
json.put("msg", errorMessage);
return json;
}
}
}
转载请注明原文地址:https://blackberry.8miu.com/read-2639.html