dubbo~全局异常拦截器的使用与设计缺陷~续

打印 上一主题 下一主题

主题 907|帖子 907|积分 2721

上一次的介绍,重要围绕怎样同一去捕获异常,以及为每一种异常添加自己的Mapper实现,并且我们知道,当在ExceptionMapper中返回非200的Response,不支持application/json的响应类型,而是写死的text/plain类型。
Filter为二方包异常手动捕获

参考:https://blog.csdn.net/2401_84048290/article/details/138105184
我们来看看dubbo的源码进行分析,如果Dubbo的provider端 抛出异常(Throwable),则会被 provider端 的ExceptionFilter拦截到,执行以下invoke方法,里面有个实现Listener类,重写了onResponse,我们可以自界说filter来覆盖原来的ExceptionFilter,把自界说的异常通过RuntimeException进行包裹,然后在Mapper中进行同一的捕获。

  • 添加CustomExceptionFilter类型,实现Filter和BaseFilter.Listener,重写onResponse方法,添加自界说代码,如下:
  1. public class CustomExceptionFilter implements Filter, BaseFilter.Listener {
  2.     public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
  3.                 exception = appResponse.getException();
  4.                                 String className = exception.getClass().getName();
  5.                                 // 本项目的异常也直接抛出
  6.                                 if (className.startsWith("com.myself.")) {
  7.                                         appResponse.setException(new RuntimeException(exception));
  8.                                         return;
  9.                                 }
  10.                                 // 其它原来ExceptionFilter中的代码
  11.     }
  12. }
复制代码

  • META-INF中注册这个过滤器resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter
  1. customExceptionFilter=com.xxx.register.exception.filter.CustomExceptionFilter
复制代码

  • 配置中文中注册,并移除默认的resources/application.properties
  1. # 自定义过滤器,上面-exception就是dubbo默认的处理异常的filter,前面-号就代表去除,注意:不需要加双引号
  2. dubbo.provider.filter=customExceptionFilter,-exception
复制代码
一个Mapper处理全部自界说异常


  • 配置文件中指定mapper,resources/application.properties
  1. dubbo.protocols.http.extension=com.xxx.register.exception.mapper.CustomExceptionMapper
复制代码

  • mapper源码如下
  1. @Provider
  2. public class DbViolationExceptionMapper implements ExceptionMapper<RuntimeException> {
  3.         @Override
  4.         public Response toResponse(RuntimeException exception) {
  5.                 Map<String, String> map = MapUtil.<String, String>builder().put("error", exception.getMessage()).build();
  6.                 if (exception.getCause() instanceof ForbiddenException) {
  7.                         return Response.status(Response.Status.FORBIDDEN).entity(map).type(MediaType.APPLICATION_JSON).build();
  8.                 }
  9.                 if (exception.getCause() instanceof CustomException) {
  10.                         return Response.status(Response.Status.BAD_REQUEST).entity(map).type(MediaType.APPLICATION_JSON).build();
  11.                 }
  12.                 if (exception.getCause() instanceof IdentityBrokerException) {
  13.                         return Response.status(Response.Status.UNAUTHORIZED).entity(map).type(MediaType.APPLICATION_JSON).build();
  14.                 }
  15.                 if (exception.getCause() instanceof UniqueException) {
  16.                         return Response.status(Response.Status.SERVICE_UNAVAILABLE).entity(map).type(MediaType.APPLICATION_JSON)
  17.                                         .build();
  18.                 }
  19.                 return Response.status(Response.Status.SERVICE_UNAVAILABLE)
  20.                                 .entity(MapUtil.builder().put("error", exception.getMessage()).build()).type(MediaType.APPLICATION_JSON)
  21.                                 .encoding("utf-8").build();// 非200的请求,这个type无效,一直是text/plain
  22.         }
  23. }
复制代码
未解决的问题


  • 目前非200的请求,toResponse时,响应类型照旧text/plain


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

数据人与超自然意识

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表