/** * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com). *

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springblade.gateway.handler; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.springblade.gateway.provider.ResponseProvider; import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.core.io.buffer.DataBufferFactory; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.lang.NonNull; import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * 异常处理 * * @author Chill */ @Order(-1) @Configuration(proxyBeanMethods = false) @RequiredArgsConstructor public class ErrorExceptionHandler implements ErrorWebExceptionHandler { private final ObjectMapper objectMapper; @NonNull @Override public Mono handle(ServerWebExchange exchange, @NonNull Throwable ex) { ServerHttpRequest request = exchange.getRequest(); ServerHttpResponse response = exchange.getResponse(); if (response.isCommitted()) { return Mono.error(ex); } response.getHeaders().setContentType(MediaType.APPLICATION_JSON); if (ex instanceof ResponseStatusException) { response.setStatusCode(((ResponseStatusException) ex).getStatus()); } return response.writeWith(Mono.fromSupplier(() -> { DataBufferFactory bufferFactory = response.bufferFactory(); try { HttpStatus status = HttpStatus.BAD_GATEWAY; if (ex instanceof ResponseStatusException) { status = ((ResponseStatusException) ex).getStatus(); } return bufferFactory.wrap(objectMapper.writeValueAsBytes(ResponseProvider.response(status.value(), buildMessage(request, ex)))); } catch (JsonProcessingException e) { e.printStackTrace(); return bufferFactory.wrap(new byte[0]); } })); } /** * 构建异常信息 */ private String buildMessage(ServerHttpRequest request, Throwable ex) { String uri = request.getURI().toString(); if (uri.endsWith("doc.html")) { return "[Swagger聚合网关] 已迁移至 [blade-swagger] 服务,请开启 [blade-swagger] 服务并访问 [http://127.0.0.1:18000/doc.html]"; } StringBuilder message = new StringBuilder("Failed to handle request ["); message.append(request.getMethodValue()); message.append(" "); message.append(request.getURI()); message.append("]"); if (ex != null) { message.append(": "); message.append(ex.getMessage()); } return message.toString(); } }