事件:记一次在开发支付时候NPE的问题
前言
最近有一个关于系统支付的功能需求,是系统所有的支付渠道都支持积分抵扣的功能,其实这个功能还蛮容易的,只是在支付中加入对用户积分的扣减、在支付异常时,对用户积分的回填,至于为什么不能在创建订单的时候冻结用户积分,是因为第三方积分接口不支持冻结、解冻功能。
UML图

代码示例

支付流程代码步骤如下:
根据订单号获取订单集合
根据订单获取订单的积分
如果订单存在积分的话调用三方积分API,抵扣积分
调用支付API,扣减金额
这段代码看起来没有问题,对各种情况都做了判断,尤其是各种为空的问题,但在转测的时候,在测试环境,测试同事在手机上点击去支付的时候,发现服务日志一直报“用户授权失败”!why?
我们首先问了下前端同事,前端支付这块是否有改动过,确认没有,并且在最近一周内也成功支付过。然后又在日志中确认token一直是有传的,并且是正确的。所以,我们把问题定位到是不是这次修改的支付代码有问题。
经本地启动,购买一个商品去支付,发现出现了在上面第19行报“空指针”的异常,原来支付的时候,没有花积分,只是全金额支付。那points这个字段是默认不赋值的吗?我们的订单是存放在mongodb中,拉取历史订单发现当不花积分的时候,文档是不存这个字段的,那问题找到了,只要加个非空处理就ok了,改完重新编译,可以支付了。

拓展
我在本地又写了一个demo,研究是哪里报的这个NPE的问题。

报错如下所示:

根据日志来看,是sum()方法报错,我通过debug源码发现,sum()方法就是循环调用mapToLong中的accept()方法,即mapToLong(i.getPoints())这块。
这块获取一定是空的,因为我们没有赋值,以后写lambda一定要谨慎对待“java.lang.NullPointerException”!
写在最后
好兄弟可以点赞并关注我的公众号“javaAnswer”,全部都是干货。