直接贴代码,如下:
import com.alibaba.fastjson.JSON; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.error.ErrorAttributeOptions; import org.springframework.boot.web.reactive.error.ErrorAttributes; 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; public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler { private static Logger logger = LoggerFactory.getLogger(JsonExceptionHandler.class); public JsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties, ErrorProperties errorProperties, ApplicationContext applicationContext) { super(errorAttributes, resourceProperties, errorProperties, applicationContext); } /** * 获取异常属性 */ @Override protected Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { int code = HttpStatus.INTERNAL_SERVER_ERROR.value(); Throwable error = super.getError(request); String message; // 用于error级别记录日志,方便排查问题 message = this.buildMessage(request, error); if (error instanceof org.springframework.cloud.gateway.support.NotFoundException) { code = HttpStatus.NOT_FOUND.value(); message = "找不到url"; } // 判断是否触发限流异常 if (error instanceof com.alibaba.csp.sentinel.slots.block.flow.FlowException) { code = 409; message = "触发限流"; } return response(code, message); } /** * 指定响应处理方法为JSON处理的方法 * * @param errorAttributes */ @Override protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) { return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse); } /** * 根据code获取对应的HttpStatus * * @param errorAttributes * @return */ @Override protected int getHttpStatus(Map<String, Object> errorAttributes) { int statusCode = (int)errorAttributes.get("status"); return statusCode; } /** * 构建异常信息 * * @param request * @param ex * @return */ private String buildMessage(ServerRequest request, Throwable ex) { StringBuilder message = new StringBuilder("Failed to handle request ["); message.append(request.methodName()); message.append(" "); message.append(request.uri()); message.append("]"); if (ex != null) { message.append(": "); message.append(ex.getMessage()); } // 记录日志,方便排查问题 logger.error(message.toString(), ex); return "网络发生404"; } /** * 构建返回的JSON数据格式 * @param status * 状态码 * @param errorMessage * 异常信息 * @return */ public static Map<String, Object> response(int status, String errorMessage) { Map<String, Object> map = new HashMap<>(); map.put("code", status); map.put("status", 200);// 设置抛异常一直status为200 map.put("message", errorMessage); logger.error("异常返回 {}", map); String response = JSON.toJSONString(map); map.put("response", response); return map; } }