栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot webflux/gateway 异常处理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot webflux/gateway 异常处理

相关类

WebExceptionHandler

public interface WebExceptionHandler {

	
	Mono handle(ServerWebExchange exchange, Throwable ex);
}

ErrorWebExceptionHandler

@FunctionalInterface
public interface ErrorWebExceptionHandler extends WebExceptionHandler {

}
自定义全局异常处理

GlobalExceptionHandler

@Component
@Slf4j
public class GlobalExceptionHandler implements ErrorWebExceptionHandler {
	// 打印日志时使用
    private static final String ERROR_STACKTRACE = "Stacktrace:";
    // 异常返回的状态码
    private static final String KEY_STATUS = "httpStatus";
    // 异常返回信息主体
    private static final String KEY_BODY = "body";
    private Tracer tracer;

    public void setTracer(Tracer tracer) {
        this.tracer = tracer;
    }

    private final ObjectMapper objectMapper = new ObjectMapper();
    
    private List> messageReaders = Collections.emptyList();

    
    private List> messageWriters = Collections.emptyList();

    
    private List viewResolvers = Collections.emptyList();

    
    private final ThreadLocal> exceptionHandlerResult = new ThreadLocal<>();

    
    public void setMessageReaders(List> messageReaders) {
        Assert.notNull(messageReaders, "'messageReaders' must not be null");
        this.messageReaders = messageReaders;
    }

    
    public void setViewResolvers(List viewResolvers) {
        this.viewResolvers = viewResolvers;
    }

    
    public void setMessageWriters(List> messageWriters) {
        Assert.notNull(messageWriters, "'messageWriters' must not be null");
        this.messageWriters = messageWriters;
    }

    
    @SneakyThrows
    @Override
    public Mono handle(ServerWebExchange serverWebExchange, Throwable throwable) {
        // 按照异常类型进行处理
        Map result = new HashMap<>(2, 1);
        ServerHttpRequest request = serverWebExchange.getRequest();
        // 异常处理 此处添加自定义异常处理
        if (throwable instanceof ResponseStatusException) {
            ResponseStatusException exception = (ResponseStatusException) throwable;
            CustomExceptionResponse customExceptionResponse =
                    new CustomExceptionResponse(String.valueOf(exception.getRawStatusCode()),
                            exception.getReason(),request.getURI().getPath());
            log.debug("ResponseStatusException occurred, url: {}", request.getURI().getPath());
            log.debug(ERROR_STACKTRACE, exception);
            String body = objectMapper.writevalueAsString(customExceptionResponse);
            result.put(KEY_STATUS, exception.getStatus());
            result.put(KEY_BODY, body);
        } else {
            log.error("Exception occurred, url: {}", request.getURI().getPath());
            log.error(ERROR_STACKTRACE, throwable);
            CustomExceptionResponse customExceptionResponse =
                    new CustomExceptionResponse(null,throwable.getMessage(),
                    	request.getURI().getPath());
            String body = objectMapper.writevalueAsString(customExceptionResponse);
            result.put(KEY_STATUS, HttpStatus.INTERNAL_SERVER_ERROR);
            result.put(KEY_BODY, body);
        }
        //参考AbstractErrorWebExceptionHandler
        if (serverWebExchange.getResponse().isCommitted()) {
            return Mono.error(throwable);
        }
        exceptionHandlerResult.set(result);
        ServerRequest newRequest = ServerRequest.create(serverWebExchange, this.messageReaders);
        Span span = tracer.currentSpan();
        if (span != null) {
            span.tag("exception", throwable.toString());
            span.flush();
        }
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse).route(newRequest)
                .switchIfEmpty(Mono.error(throwable))
                .flatMap((handler) -> handler.handle(newRequest))
                .flatMap((response) -> write(serverWebExchange, response));

    }

    
    protected Mono renderErrorResponse(ServerRequest request) {
        Map result = exceptionHandlerResult.get();
        return ServerResponse.status((HttpStatus) result.get(KEY_STATUS))
                .contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(result.get(KEY_BODY)));
    }

    
    private Mono write(ServerWebExchange exchange,
                                       ServerResponse response) {
        exchange.getResponse().getHeaders()
                .setContentType(response.headers().getContentType());
        return response.writeTo(exchange, new ResponseContext());
    }

    
    private class ResponseContext implements ServerResponse.Context {


        @Override
        public List> messageWriters() {
            return GlobalExceptionHandler.this.messageWriters;
        }

        @Override
        public List viewResolvers() {
            return GlobalExceptionHandler.this.viewResolvers;
        }

    }
}

CustomExceptionResponse :

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class CustomExceptionResponse {
    private String errorCode;
    private String message;
    private String path;
}

ExceptionConfig:

@Configuration
public class ExceptionConfig {
    
    @Primary
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public ErrorWebExceptionHandler errorWebExceptionHandler(ObjectProvider> viewResolversProvider,
                                                             ServerCodecConfigurer serverCodecConfigurer,
                                                             Tracer tracer) {
        GlobalExceptionHandler globalExceptionHandler = new GlobalExceptionHandler();
        globalExceptionHandler.setTracer(tracer);
        globalExceptionHandler.setViewResolvers(viewResolversProvider.getIfAvailable(Collections::emptyList));
        globalExceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters());
        globalExceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders());
        return globalExceptionHandler;
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/731470.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号