框架:spring security oauth2 + springboot
问题描述:使用注解【@RestControllerAdvice】进行全局异常处理后,不能输出具体异常类信息,这对问题排除无疑是一场灾难,如下图。
2021-10-02 11:03:41.691 WARN 3420 --- [nio-8090-exec-1] GlobalExceptionHandle : 空指针异常,信息为:
java.lang.NullPointerException
2021-10-02 11:03:41.711 WARN 3420 --- [nio-8090-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [java.lang.NullPointerException]
全局异常处理类如下:
@RestControllerAdvice
public class GlobalExceptionHandle {
private static final Log logger = LogFactory.getLog("GlobalExceptionHandle");
@ExceptionHandler(CustomException.class)
public Result customException(CustomException e){
ResultCodeEnum resultCodeEnum = e.getResultCodeEnum();
logger.warn("自定义错误,错误码为:【"+resultCodeEnum.getCode()+",错误信息:"+resultCodeEnum.getInfo()+"】");
return Result.error(resultCodeEnum);
}
@ExceptionHandler(NullPointerException.class)
public Result nullPointException(NullPointerException e){
logger.warn("空指针异常,信息为:n"+e);
return Result.error(2000,"空指针异常。",null);
}
@ExceptionHandler(InvalidGrantException.class)
public Result invalidGrantException(InvalidGrantException e){
logger.warn("捕获到授权无效异常,异常信息为: "+e);
return Result.error(-1100,e.getMessage(),null);
}
@ExceptionHandler(Exception.class)
public Result otherException(Exception e){
logger.warn("n其它错误,具体信息为:"+e);
return Result.error(-1000,e.getMessage(),null);
}
}
发生异常的方法如下(由于username字段不存在而引发的空指针异常):
public Result test(Mapparams){ Object inp1 = params.get("username").toString(); return Result.success(params); }
我尝试在方法上添加@SneakyThrows注解仍然不能显示具体异常类信息,当尝试使用try-catch,并且使用方法e.printStackTrace()时,即可显示异常类信息。更改后代码如下:
public Result test(Mapparams){ try{ Object inp1 = params.get("username").toString(); }catch(Exception e){ e.printStackTrace(); } return Result.success(params); }
更改后错误类信息果然显示出来,如下:
2021-10-02 11:15:56.411 INFO 3710 --- [nio-8090-exec-1]
java.lang.NullPointerException
at com.datong.liran.datongssoserver.domain.users.SysUserService.test(SysUserService.java:111)
at com.datong.liran.datongssoserver.domain.users.SysUserController.exceptionTest(SysUserController.java:68)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1063)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.frameworkServlet.processRequest(frameworkServlet.java:1006)
at org.springframework.web.servlet.frameworkServlet.doPost(frameworkServlet.java:909)
显而易见,若想显示具体错误类信息,关键在于printStackTrace()方法,故初次猜想,把全局异常处理类添加printStackTrace()方法,更改后代码如下:
@RestControllerAdvice
public class GlobalExceptionHandle {
private static final Log logger = LogFactory.getLog("GlobalExceptionHandle");
@ExceptionHandler(CustomException.class)
public Result customException(CustomException e){
ResultCodeEnum resultCodeEnum = e.getResultCodeEnum();
logger.warn("自定义错误,错误码为:【"+resultCodeEnum.getCode()+",错误信息:"+resultCodeEnum.getInfo()+"】");
e.printStackTrace();
return Result.error(resultCodeEnum);
}
@ExceptionHandler(NullPointerException.class)
public Result nullPointException(NullPointerException e){
logger.warn("空指针异常,信息为:n"+e);
e.printStackTrace();
return Result.error(2000,"空指针异常。",null);
}
@ExceptionHandler(InvalidGrantException.class)
public Result invalidGrantException(InvalidGrantException e){
logger.warn("捕获到授权无效异常,异常信息为: "+e);
e.printStackTrace();
return Result.error(-1100,e.getMessage(),null);
}
@ExceptionHandler(Exception.class)
public Result otherException(Exception e){
logger.warn("n其它错误,具体信息为:"+e);
e.printStackTrace();
return Result.error(-1000,e.getMessage(),null);
}
}
更改后,把test()方法中的try-catch去除,再进行测试,错误信息终于出来,如下。
2021-10-02 10:55:48.538 WARN 3219 --- [nio-8090-exec-1] GlobalExceptionHandle : 空指针异常,信息为:
java.lang.NullPointerException
java.lang.NullPointerException
at com.datong.liran.datongssoserver.domain.users.SysUserService.test(SysUserService.java:111)
at com.datong.liran.datongssoserver.domain.users.SysUserController.exceptionTest(SysUserController.java:68)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
至此,问题解决。
总结:获取异常信息使用getMessage,若想获取异常的具体位置,则应使用方法printStackTrace()。



