Spring Cloud Gateway之全局异常拦截器
/** * @version 2019/8/14 * @description: 异常拦截器 * @modified: */ @Slf4j public class JsonExceptionHandler implements ErrorWebExceptionHandler { /** * MessageReader */ private List<HttpMessageReader<?>> messageReaders = Collections.emptyList(); /** * MessageWriter */ private List<HttpMessageWriter<?>> messageWriters = Collections.emptyList(); /** * ViewResolvers */ private List<ViewResolver> viewResolvers = Collections.emptyList(); /** * 存储处理异常后的信息 */ private ThreadLocal<ResEntity> exceptionHandlerResult = new ThreadLocal<>(); /** * 参考AbstractErrorWebExceptionHandler */ public void setMessageReaders(List<HttpMessageReader<?>> messageReaders) { Assert.notNull(messageReaders, "'messageReaders' must not be null"); this.messageReaders = messageReaders; } /** * 参考AbstractErrorWebExceptionHandler */ public void setViewResolvers(List<ViewResolver> viewResolvers) { this.viewResolvers = viewResolvers; } /** * 参考AbstractErrorWebExceptionHandler */ public void setMessageWriters(List<HttpMessageWriter<?>> messageWriters) { Assert.notNull(messageWriters, "'messageWriters' must not be null"); this.messageWriters = messageWriters; } @Override public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { // 按照异常类型进行处理 默认500 int httpStatus = HttpStatus.INTERNAL_SERVER_ERROR.value(); String body = "系统异常,请联系管理员"; if (ex instanceof NotFoundException) { httpStatus = HttpStatus.NOT_FOUND.value(); body = ex.getMessage(); }else if(ex instanceof ResponseStatusException){ ResponseStatusException responseStatusException = (ResponseStatusException) ex; httpStatus = responseStatusException.getStatus().value(); body = responseStatusException.getMessage(); } else if (ex instanceof BusinessException) { body = ex.getMessage(); httpStatus = ((BusinessException) ex).toResEntity().getHttpStatus(); } else if (ex instanceof RuntimeException) { Throwable cause = ex.getCause(); body = ex.getMessage(); if(null != cause && cause.getMessage().contains("Load balancer does not have available server for client")){ body = "服务不存在"; } } //错误记录 ServerHttpRequest request = exchange.getRequest(); log.error("[全局异常处理]异常请求路径:{}", request.getPath()); log.error("异常详细信息:{}",ex); //封装响应体 ResEntity res = new ResEntity(); res.setHttpStatus(httpStatus); res.setMsg(body); //参考AbstractErrorWebExceptionHandler if (exchange.getResponse().isCommitted()) { return Mono.error(ex); } exceptionHandlerResult.set(res); ServerRequest newRequest = ServerRequest.create(exchange, this.messageReaders); return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest) .switchIfEmpty(Mono.error(ex)) .flatMap((handler) -> handler.handle(newRequest)) .flatMap((response) -> write(exchange, response)); } /** * 参考DefaultErrorWebExceptionHandler */ protected Mono<ServerResponse> renderErrorResponse(ServerRequest request) { ResEntity result = exceptionHandlerResult.get(); //404 因前端框架问题,不转换处理 ,因此目前只有系统报500才转换为自定义的状态码 if(HttpStatus.INTERNAL_SERVER_ERROR.value() == result.getHttpStatus()){ return ServerResponse.status(HttpStatus.OK.value()) .contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(result)); } return ServerResponse.status(result.getHttpStatus()) .contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(result)); } /** * 参考AbstractErrorWebExceptionHandler */ private Mono<? extends Void> write(ServerWebExchange exchange, ServerResponse response) { exchange.getResponse().getHeaders() .setContentType(response.headers().getContentType()); return response.writeTo(exchange, new ResponseContext()); } /** * 参考AbstractErrorWebExceptionHandler */ private class ResponseContext implements ServerResponse.Context { @Override public List<HttpMessageWriter<?>> messageWriters() { return JsonExceptionHandler.this.messageWriters; } @Override public List<ViewResolver> viewResolvers() { return JsonExceptionHandler.this.viewResolvers; } } }