一、问题描述
在我的项目中,有多个场景需要通过Feign远程调用同一个接口,该接口入参只有一个,是字符串,返回值也是一个字符串。入参一模一样的情况下,当直接在其他接口中调用这个接口时,功能正常;当在xxl-job中远程调用接口是,报错空指针异常。
二、问题定位
通过打印日志,需要注意的是,我们平时打印日志可能被要求打印异常的Message()信息,常见的格式如e.getMessage()。但是如果你在定位这个问题中,使用这种异常打印方式,会发现只有一个null。无法定位此问题。此时,可以直接打印异常e。这时,可以观察到一个完整的异常信息。因某些原因,此处我不粘贴异常,仅用语言描述介绍此异常特点:可以观察到此异常的第一行,是一个空指针异常;第二行指向RequestInterceptor所在的类的方法;后面几行中可以执行远程接口被调用的方法中。
这里,重点关注第二行RequestInterceptor所在的类的方法,在我的项目中,RequestInterceptor采用的是全局配置,在重新的方法中,首先根据(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();获取一个ServletRequestAttributes对象,然后根据ServletRequestAttributes对象获取HttpServletRequest,异常正是从此处抛出。很显然(ServletRequestAttributes) RequestContextHolder.getRequestAttributes()可能获取不到的ServletRequestAttributes对象,下一步又未判空,导致出现这个异常。
三、解决办法
在ServletRequestAttributes对象获取HttpServletRequest对象之前,先判空,非空再进行下一步。
这样修改后,测试,发现在定时任务中也可以正常远程调用接口了。
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(servletRequestAttributes != null){
HttpServletRequest request = servletRequestAttributes.getRequest();
...
}