动态代理,UndeclaredThrowableException异常


最近学习 动态代理,遇见UndeclaredThrowableException异常,记录一下

异常情况

情况是我自定义了两个异常,然后使用JDK的动态代理处理事务防止数据出问题,然而在servlet里居然捕捉不到我自定义的异常
具体核心代码如下:
servlet代码

        AccountService accountService = (AccountService)Proxy.newProxyInstance(AccountService.class.getClassLoader(),
                new Class<?>[]{AccountService.class}, new AccountProxy(new AccountServiceImpl()));
        try {
            accountService.tranfer(fromactno,toactno,money);
            /*accountService.tranfer(fromactno,toactno,money);*/
            //到这里说明成功
            //调度View做页面显示
            response.sendRedirect(request.getContextPath()+"/success.jsp");
        } catch (AppException e) {
            //到这里说明失败
            //调度View做页面显示
            request.setAttribute("error",e.getMessage());
            request.getRequestDispatcher("/error.jsp").forward(request,response);
        } catch (MoneyNotEnoughException e) {
            //到这里说明失败
            //调度View做页面显示
            request.setAttribute("error",e.getMessage());
            request.getRequestDispatcher("/error.jsp").forward(request,response);
        }

协助代理类的类的invoke方法

@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        Connection conn = DButil.getConnection();
        conn.setAutoCommit(false);//开启事务
        Object invoke = method.invoke(target, args);//调用的目标代码
        conn.commit();//提交事务
        return invoke;
    }

异常情况:
请添加图片描述

原因

通过源码文档翻译可知

Throwable – 从代理实例的方法调用中抛出的异常。异常的类型必须可以分配给接口方法的throws
子句中声明的任何异常类型,或者可以分配给未经检查的异常类型java.lang.RuntimeExceptionjava.lang.Error 。如果此方法抛出了一个不能分配给接口方法的throws子句中声明的任何异常类
型的已检查异常,则包含此方法抛出的异常的UndeclaredThrowableException将由方法调用抛出代
理实例。
 public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;

简单来说该方法抛出的检查型异常,不属于runtimeexception和error,也没有在throws中定义,这个异常会被归类到Throwable,而自定义的异常是继承 Exception 更加广泛的检查型异常,通过JDK动态代理代码调用我们发现,该方法会抛出 InvocationTargetException的检查型异常,称为调用目标异常,而我们自定义的异常将会被InvocationTargetException收录,如果没有通过throw定义抛出,则此方法抛出UndeclaredThrowableException异常
请添加图片描述

解决方法

知道原因就好办,自定义的异常会被InvocationTargetException收录,我们就可以在invoke方法中捕捉该异常,通过throw将异常信息抛出,就可以从servlet中精确捕捉自定义的异常
如下

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Connection conn = null;
        Object invoke = null;
        try {
            conn = DButil.getConnection();
            conn.setAutoCommit(false);//开启事务
            invoke = method.invoke(target, args);//调用的目标代码
            conn.commit();//提交事务
        } catch (InvocationTargetException e) {
            if (conn != null) {
                conn.rollback();//遇到异常回滚事务
            }
            throw e.getCause();//异常抛出
        }finally {
            DButil.close(conn,null,null);//关闭资源
        }
        return invoke;
    }
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忆亦何为

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值