springMVC统一异常处理

目标:

1: 异常统一处理

2: 记录异常方法的参数名称和值


系统很多地方都会抛出异常, 而Java的异常体系目标就是与逻辑解耦. 所以项目中如果每个异常都单独处理,则太累也没必要.

SpringMVC 提供了 统一的异常处理方法.

异常出现的时候,我们很想知道客户端传的参数是什么,对于判断异常原因也很有帮助, spring aop 就可以获取 方法参数名称和值


1: 异常统一处理

Spring MVC处理异常有3种方式: 
(1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver; 
(2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器; 
(3)使用@ExceptionHandler注解实现异常处理; 

我们这里使用第二种. 先创建个异常处理类

[java]  view plain  copy
 print ?
  1. public class MyExceptionHandler implements HandlerExceptionResolver{  
  2.     private Logger logger = Logger.getLogger(MyExceptionHandler.class);  
  3.       
  4.     @Override  
  5.     public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,  
  6.             Exception ex) {  
  7.         Map map = new HashMap();  
  8.         logger.error(ex.getMessage(),ex);  
  9.         if(ex instanceof MaxUploadSizeExceededException){  
  10.             map.put("msg""文件大小超过限制!");  
  11.             return new ModelAndView(new MappingJackson2JsonView(),map);  
  12.         }  
  13.         map.put("msg""系统错误!");  
  14.         return new ModelAndView(new MappingJackson2JsonView(),map);  
  15.     }  
  16. }  

这个异常类里面, 我们打印了异常日志,并且对某种异常类型(这里是上传文件过大)做了特殊处理. 返回值这里用的是返回json格式的.


然后在配置文件(这里放在spring-mvc.xml)中将exceptionHandler指向我们自己写的类

[html]  view plain  copy
 print ?
  1. <bean id="exceptionHandler" class="com.dingcheng.common.exception.MyExceptionHandler"/>  

就这么简单,就可以了.


2: 记录异常方法的参数名称和值

这大概分为2步, 首先拦截到controller的bean, 其次获取异常方法的参数

1)拦截controller

需要在spring-mvc.xml文件中配置spirng的aop:config,指定拦截的bean和用来处理拦截的类

[html]  view plain  copy
 print ?
  1. <bean id="paramAspect" class="com.dingcheng.common.aop.ParamAspect" />    
  2. <aop:config>  
  3.     <aop:aspect id="exParamAspect" ref="paramAspect">    
  4.            <aop:pointcut id="exParam" expression="execution(* com.dingcheng.*.controller.*.*(..))" />    
  5.            <aop:after-throwing pointcut-ref="exParam" method="doThrowing" throwing="ex" />    
  6.        aop:aspect>   
  7. aop:config>   

这个aop配置要放在 spring-mvc里面,如果放在application-context.xml或者spring-mybatis.xml中可能不行.

这里配置了 aop:after-throwing, 用于方法抛出异常后调用, 当然也可以配置其他的 before,around等.


再来看看ParamAspect这个类

[java]  view plain  copy
 print ?
  1. public class ParamAspect {  
  2.     private Logger logger = Logger.getLogger(ParamAspect.class);  
  3.   
  4.     public void doThrowing(JoinPoint jp, Throwable ex) {  
  5.         //获取参数名  
  6.         Signature signature = jp.getSignature();  
  7.         MethodSignature methodSignature = (MethodSignature) signature;  
  8.         String[] paramNameArr = methodSignature.getParameterNames();  
  9.   
  10.         //获取参数值  
  11.         Object[] paramValueArr = jp.getArgs();  
  12.         StringBuilder sbd = new StringBuilder("pparam-->");  
  13.         for(int i=0;i
  14.             sbd.append(paramNameArr[i]+":"+paramValueArr[i]+",");  
  15.         }  
  16.         logger.error(sbd);  
  17.     }  
  18. }  

doThrowing方法对应aop:after-throwing里面配置的method.


2)获取异常方法的参数

上面的代码中,doThrowing方法里面已经实现了 获取异常方法参数名称和值的方法


3.测试下

[java]  view plain  copy
 print ?
  1. @RequestMapping(value = "add.action", method = RequestMethod.POST)  
  2. public String list(Model model, String loginName,String password) {  
  3.     User user = new User();  
  4.     user.setLoginName(loginName);  
  5.     user.setPassword(password);  
  6.     userService.create(user);  
  7.     if(userService!=null){  
  8.         throw new RuntimeException("测试一下");  
  9.     }  
  10.     return "redirect:list.action";  
  11. }  


源码地址:https://code.csdn.net/qq315737546/ssmq/tree/master

你可能感兴趣的:(java基础)