项目使用过的是apache dubbo 2.7.1, 封装了自定义全局统一的异常处理器。

统一异常处理器

需要实现javax.ws.rs.ext.ExceptionMapper接口。

import org.apache.dubbo.rpc.RpcException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jboss.resteasy.spi.DefaultOptionsMethodException;
import org.springframework.util.StringUtils;import javax.exceptions.ServiceException;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;/*** 全局统一的异常处理器。*/
public class CustomExceptionMapper implements ExceptionMapper<Exception> {private final static Logger logger = LogManager.getLogger(CustomExceptionMapper.class);private static final String TEXT_PLAIN_UTF_8 = "text/plain; charset=UTF-8";private static final String JSON_UTF_8 = "application/json;charset=UTF-8";private static final int FILTER_SIZE = 60;private static final String DEV = "dev";private static final String TEST = "test";private static final int UNAUTHORIZED = 401;public static String active;public static void setActive(String at) {active = at;}@Overridepublic Response toResponse(Exception e) {if (e instanceof DefaultOptionsMethodException ||(StringUtils.hasText(e.getMessage()) && e.getMessage().contains("org.jboss.resteasy.spi.DefaultOptionsMethodException"))) {// 忽略此异常: Option跨域请求探测return Response.status(Response.Status.OK).type(TEXT_PLAIN_UTF_8).build();}Response.Status httpStatus = Response.Status.INTERNAL_SERVER_ERROR;Result<String> errorResult = null;List<String> messages = new ArrayList<>();if (e.getStackTrace().length > 0) {StackTraceElement ste = e.getStackTrace()[0];messages.add("异常内容:" + e.getMessage());messages.add("异常名:" + e.getClass());messages.add("异常类名:" + ste.getClassName());messages.add("异常文件名:" + ste.getFileName());messages.add("异常行号:" + ste.getLineNumber());messages.add("异常方法:" + ste.getMethodName());}//1.处理404异常if (e instanceof NotFoundException) {logger.error("发生404异常: ", e);errorResult = fail(404, "404 not found!");httpStatus = Response.Status.NOT_FOUND;}//2.dubbo远程调用异常if (e instanceof RpcException) {errorResult = fail(ErrorCodeEnums.InternalServerError.getCode(), "服务重新连线中,请稍后", messages);httpStatus = Response.Status.UNAUTHORIZED;}//3.非法参数异常if (e instanceof IllegalArgumentException) {if (!StringUtils.isEmpty(e.getMessage())) {errorResult = fail(ErrorCodeEnums.InternalServerError.getCode(), filterChinese(e.getMessage()), messages);} else {errorResult = fail(ErrorCodeEnums.InternalServerError.getCode(), filterChinese("内部错误:A04"), messages);}}//4.对象解析异常if (e instanceof IllegalStateException) {if (StringUtils.isEmpty(e.getMessage())) {errorResult = fail(ErrorCodeEnums.InternalServerError.getCode(), filterChinese("内部错误:A03"), messages);} else {errorResult = fail(ErrorCodeEnums.InternalServerError.getCode(), filterChinese(e.getMessage()), messages);}}//5.强制转换异常if (e instanceof ClassCastException) {errorResult = fail(ErrorCodeEnums.InternalServerError.getCode(), "内部错误:A01", messages);}//6.空指针if (e instanceof NullPointerException) {errorResult = fail(ErrorCodeEnums.InternalServerError.getCode(), "内部错误:A02", messages);}//7.处理自定义异常if (e instanceof AlertException) {errorResult = fail(((AlertException) e).getErrorCode(), e.getMessage(), messages);logger.error("提示信息:{}", e.getMessage());} else if (e instanceof AlertAndReloadException) {errorResult = fail(((AlertAndReloadException) e).getErrorCode(), e.getMessage(), messages);logger.error("提示信息:{}", e.getMessage());} else if (e instanceof ServiceException) {ServiceException serviceException = (ServiceException) e;//统一异常码Integer errorCode = serviceException.getErrorCode();String errorInfo = serviceException.getErrorInfo();if ((!StringUtils.isEmpty(errorCode)) && errorCode == UNAUTHORIZED) {httpStatus = Response.Status.UNAUTHORIZED;}if (StringUtils.isEmpty(errorCode)) {errorCode = Response.Status.INTERNAL_SERVER_ERROR.getStatusCode();}if (httpStatus == Response.Status.UNAUTHORIZED) {logger.debug("发生自定义异常,异常码:{}, 异常说明:{}", errorCode, errorInfo);} else {logger.error("发生自定义异常,异常码:{}, 异常说明:{}", errorCode, errorInfo, e);}//错误提示信息String reason = StringUtils.hasText(errorInfo) ? errorInfo : ErrorCodeEnums.getByCode(errorCode);errorResult = fail(errorCode, StringUtils.hasText(reason) ? reason : errorInfo, messages);}//8.其他异常if (errorResult == null) {logger.error("发生异常: ", e);String msg = e.getMessage();if (StringUtils.isEmpty(msg) || msg.length() > FILTER_SIZE) {msg = "服务器开小差了,请重试";}if (!StringUtils.isEmpty(active) && (active.equals(DEV) || active.equals(TEST))) {errorResult = fail(ErrorCodeEnums.InternalServerError.getCode(), msg, getExceptionDetail(e), messages);} else {errorResult = fail(ErrorCodeEnums.InternalServerError.getCode(), msg, messages);}}return Response.status(httpStatus).entity(errorResult.toString()).type(JSON_UTF_8).build();}private Result<String> fail(int code, String msg) {return new Result<>(code, msg);}private Result<String> fail(int code, String msg, List<String> messages) {return new Result<>(code, msg, null, messages);}private Result<String> fail(int code, String msg, String errMessage) {return new Result<>(code, msg, errMessage);}private Result<String> fail(int code, String msg, String errMessage, List<String> messages) {return new Result<>(code, msg, errMessage, messages);}/*** 过滤掉 非中文字符。*/private static String filterChinese(final String str) {if (!StringUtils.hasText(str)) {return str;}if (str.length() <= FILTER_SIZE) {return str;}//只保留前60个中文字符String filterStr = str.replaceAll("[^(\\u4e00-\\u9fa5)]", "").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("\\.", "").replaceAll("\\_", "");if (StringUtils.isEmpty(filterStr)) {//过滤后为空,则原样显示前60个字符return str.substring(0, FILTER_SIZE);} else if (filterStr.length() > FILTER_SIZE) {return filterStr.substring(0, FILTER_SIZE);} else if (filterStr.length() < 15) {return str;} else {return filterStr;}}/*** 获取异常详细信息*/public static String getExceptionDetail(Exception ex) {String ret = null;try {ByteArrayOutputStream out = new ByteArrayOutputStream();PrintStream pout = new PrintStream(out);ex.printStackTrace(pout);ret = new String(out.toByteArray());pout.close();out.close();} catch (Exception e) {}return ret;}}

统一异常码枚举类 ErrorCodeEnums.java:

/*** 全局统一的异常码。*/
public enum ErrorCodeEnums {// ----------------- http标准状态码---------------------------------Unauthorized(401, "请先登录"),Forbidden(403, "您无权限访问此页面,请联系管理员或重新登录"),NotFound(404, "抱歉,您访问的页面不存在"),InternalServerError(500, "服务器内部错误"),//----------------- 自定义异常码 -----------------------------------ServerErrorRetry(666, "服务器内部错误,前端页面尝试再次调用接口直到返回666"),ParamsError(1001, "参数校验失败"),TokenExpired(1002, "登录token已过期"),AlertMsg(1003, "页面提示信息"),AlertMsgAndReload(1004, "提示信息,并自动刷新页面"),;/*** 异常码。*/public Integer code;/*** 异常描述。*/public String reason;ErrorCodeEnums(Integer code, String reason) {this.code = code;this.reason = reason;}public static String getByCode(Integer code) {for (ErrorCodeEnums item : ErrorCodeEnums.values()) {if (code.equals(item.getCode())) {return item.reason;}}return "";}public Integer getCode() {return code;}public String getReason() {return reason;}
}

application.yml文件配置

在application.yml文件中配置启用

dubbo:application:name: xxx-service# 优雅停机超时时间shutwait: 15000provider:#负载均衡loadbalance: roundrobintimeout: 10000filter: xxxFilterconsumer: #关闭启动时检查依赖服务check: falsefilter: xxxFilterprotocols:dubbo:name: dubboport: -1server: nettyextension: xxx.CustomExceptionMapperrest:name: restport: 80server: tomcatcontextpath: xxx-serviceextension: xxx.CustomExceptionMapper

apache dubbo 自定义全局统一的异常处理器相关推荐

  1. SpringBoot定义全局统一业务异常,且处理filter里面的异常

    SpringBoot定义全局统一业务异常,且处理filter里面的异常 参考文章: (1)SpringBoot定义全局统一业务异常,且处理filter里面的异常 (2)https://www.cnbl ...

  2. Spring Boot电商项目17:用户模块六:注册接口开发之:使用【GlobalExceptionHandler】来全局统一处理异常;(涉及了@ControllerAdvice等注解)

    说明: (1)为什么写这篇博客?:在[Spring Boot电商项目15:用户模块四:注册接口开发:]中,在Service层中遇到了[用户名重复]的情况,然后Service层把这个情况做成了一个异常, ...

  3. C++ Qt全局异常处理器_异常处理

    异常处理是编程中十分重要但也最容易被人忽视的语言特性,它为开发者提供了处理程序运行时错误的机制,对于程序设计来说正确的异常处理能够防止泄露程序自身细节给用户,给开发者提供完整的错误回溯堆栈,同时也能提 ...

  4. SpringMVC构建全局异常处理器

    异常处理器 SpringMVC提供全局异常处理器进行统一的异常处理,一个系统只能有一个异常处理器. 系统的dao.service.controller层出现异常的时候都throws Exception ...

  5. SpringMVC第六篇【校验、统一处理异常】

    Validation 在我们的Struts2中,我们是继承ActionSupport来实现校验的-它有两种方式来实现校验的功能 手写代码 XML配置 这两种方式也是可以特定处理方法或者整个Action ...

  6. SpringMVC异常处理器代码示例

    异常处理器 springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 异常处理思路 Throwable(error,Exception) ...

  7. Apache Dubbo 的协议帧与编解码原理

    前言 Apache Dubbo 是阿里巴巴开源的高性能可扩展分布式 RPC 框架,目前其在各大厂内部被广泛使用.RPC 框架客户端在发送消息前会对 POJO 的消息内容编码为二进制流,然后通过 TCP ...

  8. Spring MVC的异常处理器

    异常处理器 异常处理思路 Java 中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试等手段减少运行时异常的发生. ...

  9. SpringBoot 自定义全局异常处理器

    SpringBoot自定义全局异常处理器 一.maven依赖 二.GlobalExceptionHandler.java 三.ResponseStandard.java 四.logback.xml 五 ...

最新文章

  1. 让 Linux 防火墙新秀 nftables 为你的 VPS 保驾护航
  2. html5 去掉 li的样式,css li 去掉点的样式写法
  3. django_rest_framework—路由器机制
  4. stylegan-encoder代码执行步骤和解释
  5. 被字句15个_文旅部重新认定国级非遗保护单位,潮州15项花落谁家?这些非遗你都认得吗?...
  6. 127.0.0.1 zxt.php_windows 10 下docker布置nginx+php环境,用宿主WEB目录负载均衡
  7. 反诈题库---合计100道(解析版最新)
  8. 学校图书馆座位预约系统微信小程序开发制作介绍
  9. 形式语言与自动机理论蒋宗礼 第五章答案
  10. php layim 图片正则替换,用正则表达式批量替换图片路径方法
  11. 安卓模拟PC浏览器发送http请求
  12. Spring Boot做国际化
  13. python wechat_wechat-sdk
  14. 30亿流量!梨视频靠什么拍出个“短视频世界杯元年”
  15. ORACLE 培训教程(1)
  16. Appium 发送发送本机相册的图片
  17. 分体式8通道R2000方案智能柜超高频RFID读写器|开发板HXU2889EVB的应用与接口说明
  18. 前端面试题之CSS布局问题
  19. java o 验证码识别_验证码识别(一)
  20. mysql5.7中文全文检索,让MySQL支持中文全文检索

热门文章

  1. 2021年有不加班的选择吗?哪些城市加班最严重?
  2. 从Q4财报,看有道如何实现从在线教育“迷途”中脱身?
  3. 魔幻的“净醛产品”:宜家被罚“亡羊”,欧派用视频“补牢”?
  4. 自动滑动图片html5,html+css+js 实现自动滑动轮播图
  5. 部署linux的环境,Jenkins安装与配置
  6. 文件系统服务器管理论文,Linux管理磁盘和文件系统
  7. 快速谱峭度matlab,一种基于快速谱峭度分析的泵潜在空化故障检测方法与流程
  8. c语言改java语言,请教怎么把这个JAVA程序改成C语言能够运行啊
  9. php yii2.0 读取excel,yii2.0使用excel Gridview读取excel内容
  10. java engine_java使用OGEngine开发2048