今天遇到一个问题,并不是技术上很牛逼,只是有一点灵异,如何灵异的呢?因为我第一次部署测试没有反应,但是当我实在是hold不住,调试spring mvc源码的时候,它悄悄的,竟然好了。。。。。由此而产生的最直接后果是,当第一次我测试失败后,我直接否定了这个方案转而尝试其他方案,结果导致了我浪费了很多时间。。。。。
个中蛋疼问题,心力憔悴之处暂且不表,言归正传。
应用场景:
Spring MVC中拦截器拦截项目中的Exception,这很正常,不正常的是,要求在拦截这个异常的时候记录下发生异常的方法名,参数,在Spring MVC的拦截器中我们实现了HandlerExceptionResolver,重写的方法为public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {}
在这里我只拿到Exception的信息,而无法直接得知出错的方法名和出错时的参数。
因为Spring MVC的容器和Spring Core的容器不是同一个,这个问题的关键,我无法直接获取我想要的信息,好吧,为了我那可怜的工资,我辈只能奋不顾身。
PS :因为一些信息的原因,有些敏感字符也删除,各位勿喷。
首先:定义一个AOP,先写一个简单的Class,
public class ExceptionAdvisor{
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();
Object[] args = joinPoint.getArgs();
String methodName = method.getName();
StringBuilder builder = new StringBuilder(512);
builder.append("\nMethod Name is :").append(methodName).append("\n");
if (args != null) {
int size = args.length;
builder.append("Method Args:\n");
for (int index = 0; index < size; index ++) {
Object object = args[index];
builder.append("args[").append(index).append("]:").append(object.toString()).append("\n");
}
}
builder.append(ex.getMessage());
throw new RuntimeException(builder.toString());
}
}
注意上述的做法是,先把我需要的信息拼装起来,然后重新throw一个RuntimeException
同样的,上配置文件:
<bean id="exceptionadvice" class="com.playsnail.platform.exception.handler.ExceptionAdvisor" />
<aop:config proxy-target-class="true">
<aop:aspect ref="exceptionadvice" >
<aop:after-throwing method="afterThrowing" pointcut="execution (* 路径..*.*(..))" throwing="ex"/>
</aop:aspect>
</aop:config>
这样便拦截到了Spring core里面的异常。
当我们throw新的RuntimeException后,就需要Spring MVC的拦截器闪亮登场。
public class ExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
//此处的Exception就是AOP重新抛出的Exception了,现在对重新抛出的异常做你想做的事情
return new ModelAndView();
}
同样的,不能少了配置文件,在spring MVC的配置文件中增加
<bean id="exceptionResolver" class="路径.ExceptionHandler "></bean>
OK, 简单吧,但是摸索的过程是痛苦的,特别有一些灵异事件以后。
上面是milestone版,后期可能会出现一些变动,还需要实践的证明,各位看官有什么指正之处或者有什么更好的办法,欢迎各位狂喷。