上一次的介绍,主要围绕如何统一去捕获异常,以及为每一种异常添加自己的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方法,添加自定义代码,如下:
public class CustomExceptionFilter implements Filter, BaseFilter.Listener {
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
exception = appResponse.getException();
String className = exception.getClass().getName(); // 本项目的异常也直接抛出
if (className.startsWith("com.myself.")) {
appResponse.setException(new RuntimeException(exception));
return;
}
// 其它原来ExceptionFilter中的代码
}
}
  • META-INF中注册这个过滤器resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter
customExceptionFilter=com.xxx.register.exception.filter.CustomExceptionFilter
  • 配置中文中注册,并移除默认的resources/application.properties
# 自定义过滤器,上面-exception就是dubbo默认的处理异常的filter,前面-号就代表去除,注意:不需要加双引号
dubbo.provider.filter=customExceptionFilter,-exception

一个Mapper处理所有自定义异常

  • 配置文件中指定mapper,resources/application.properties
dubbo.protocols.http.extension=com.xxx.register.exception.mapper.CustomExceptionMapper
  • mapper源码如下
@Provider
public class DbViolationExceptionMapper implements ExceptionMapper<RuntimeException> { @Override
public Response toResponse(RuntimeException exception) {
Map<String, String> map = MapUtil.<String, String>builder().put("error", exception.getMessage()).build();
if (exception.getCause() instanceof ForbiddenException) {
return Response.status(Response.Status.FORBIDDEN).entity(map).type(MediaType.APPLICATION_JSON).build();
}
if (exception.getCause() instanceof CustomException) {
return Response.status(Response.Status.BAD_REQUEST).entity(map).type(MediaType.APPLICATION_JSON).build();
}
if (exception.getCause() instanceof IdentityBrokerException) {
return Response.status(Response.Status.UNAUTHORIZED).entity(map).type(MediaType.APPLICATION_JSON).build();
}
if (exception.getCause() instanceof UniqueException) {
return Response.status(Response.Status.SERVICE_UNAVAILABLE).entity(map).type(MediaType.APPLICATION_JSON)
.build();
}
return Response.status(Response.Status.SERVICE_UNAVAILABLE)
.entity(MapUtil.builder().put("error", exception.getMessage()).build()).type(MediaType.APPLICATION_JSON)
.encoding("utf-8").build();// 非200的请求,这个type无效,一直是text/plain } }

未解决的问题

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

dubbo~全局异常拦截器的使用与设计缺陷~续的更多相关文章

  1. Spring Cloud Gateway之全局异常拦截器

    /** * @version 2019/8/14 * @description: 异常拦截器 * @modified: */ @Slf4j public class JsonExceptionHand ...

  2. Asp.Netcore使用Filter来实现接口的全局异常拦截,以及前置拦截和后置拦截

    原文链接:https://blog.csdn.net/qq_38762313/article/details/85234594 全局异常拦截器:       解决写每个接口都需要去做容错而添加try{ ...

  3. 我心中的核心组件(可插拔的AOP)~第四回 异常拦截器

    回到目录 之前说过有关拦截器的文章,第二回  缓存拦截器,事实上,在那讲里说的最多是AOP和缓存组件,对于拦截的概念并没有详细的说明,这一讲,不说AOP,主要说一下拦截器,拦截器Interceptio ...

  4. Java自定义异常类以及异常拦截器

    自定义异常类不难,但下面这个方法,它的核心是异常拦截器类. 就算是在分布式系统间进行传递也可以,只要最顶层的服务有这个异常拦截器类(下例是在 springboot 项目中) 1.自定义异常类,继承自 ...

  5. Spring 全局异常拦截根据业务返回不同格式数据 自定义异常

    1.全局异常拦截:针对所有异常进行拦截 可根据请求自定义返回格式 2.自定义异常类 处理不同业务的异常 接下来开始入手代码: 1).自定义异常类 @ControllerAdvice//添加注解 记得开 ...

  6. SpringBoot全局异常拦截

    SpringBoot全局异常捕获 使用到的技能 @RestControllerAdvice或(@ControllerAdvice+@ResponseBody) @ExceptionHandler 代码 ...

  7. SpringBoot 全局异常拦截捕获处理

    一.全局异常处理 //Result定义全局数据返回对象 package com.xiaobing.demo001.domain; public class Result { private Integ ...

  8. Dubbo自定义日志拦截器

    前言 上一篇文章 Spring aop+自定义注解统一记录用户行为日志 记录了 web层中通过自定义注解配合Spring aop自动记录用户行为日志的过程.那么按照分布式架构中Dubbo服务层的调用过 ...

  9. @ControllerAdvice全局异常拦截

    @ControllerAdvice 拦截异常并统一处理 在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler.@InitBinder ...

  10. springboot实现定时任务,异步操作,统一结果返回,全局异常处理,拦截器及事务处理

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 本文都是springboot的常用和实用功能,话不多说开始吧 定时任务 1.启动类开启注解 @EnableScheduling //开启基于注解 ...

随机推荐

  1. 牛客网-SQL专项训练17

    ①SQL查询中使用WHere子句指出的是:查询条件 ②Mysql中表student_table(id,name,birth,sex),查询重复姓名.重复次数,并按重复次数降序排列,正确的是(A)? 解 ...

  2. 科普达人丨一图看懂阿里云ECS

    简介: 建议收藏  原文链接:https://click.aliyun.com/m/1000363154/ 本文为阿里云原创内容,未经允许不得转载.

  3. Fury:一个基于JIT动态编译的高性能多语言原生序列化框架

    简介: Fury是一个基于JIT动态编译的多语言原生序列化框架,支持Java/Python/Golang/C++等语言,提供全自动的对象多语言/跨语言序列化能力,以及相比于别的框架最高20~200倍的 ...

  4. Serverless 选型:深度解读 Serverless 架构及平台选择

    作者 | 悟鹏  阿里巴巴技术专家 导读:本文尝试以日常开发流程为起点,分析开发者在每个阶段要面对的问题,然后组合解决方案,提炼面向 Serverless 的开发模型,并与业界提出的 Serverle ...

  5. 电路笔记03—kcl、kvl,独立源,受控源

    电路笔记03-kcl.kvl,独立源,受控源 听起来简单,做起来需要思考.所以做作业,思考很有 必要.电路的功率守恒,4种受控源,用两类约束列方程.电路分析力最难的一部分,怎么把一个量用其它量表示,后 ...

  6. C语言程序设计-笔记7-指针

    C语言程序设计-笔记7-指针 例8-1  利用指针模拟密码开锁游戏. #include<stdio.h> int main(void) { int x=5342;          //变 ...

  7. 大数据面试SQL每日一题系列:最高峰同时在线主播人数。字节,快手等大厂高频面试题

    大数据面试SQL每日一题系列:最高峰同时在线主播人数.字节,快手等大厂高频面试题 之后会不定期更新每日一题sql系列. SQL面试题每日一题系列内容均来自于网络以及实际使用情况收集,如有雷同,纯属巧合 ...

  8. CCE云原生混部场景下的测试案例

    本文分享自华为云社区<CCE云原生混部场景下在线任务抢占.压制离线任务CPU资源.保障在线任务服务质量效果测试>,作者:可以交个朋友. 背景 企业的 IT 环境通常运行两大类进程,一类是在 ...

  9. Vue的Vue-ls使用

    Vue插件,用于从Vue上下文中使用本地Storage,会话Storage和内存Storage 1. 安装 NPM npm install vue-ls --save YARN yarn add vu ...

  10. Java面试题:Spring Bean线程安全?别担心,只要你不写并发代码就好了!

    Spring中的Bean是否线程安全取决于Bean的作用域(scope).Spring提供了几种不同的Scope,其中包括Singleton.Prototype.Request.Session.Glo ...