目标:
1: 异常统一处理
2: 记录异常方法的参数名称和值
系统很多地方都会抛出异常, 而Java的异常体系目标就是与逻辑解耦. 所以项目中如果每个异常都单独处理,则太累也没必要.
SpringMVC 提供了 统一的异常处理方法.
异常出现的时候,我们很想知道客户端传的参数是什么,对于判断异常原因也很有帮助, spring aop 就可以获取 方法参数名称和值
1: 异常统一处理
Spring MVC处理异常有3种方式:
(1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver;
(2)实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
(3)使用@ExceptionHandler注解实现异常处理;
我们这里使用第二种. 先创建个异常处理类
- public class MyExceptionHandler implements HandlerExceptionResolver{
- private Logger logger = Logger.getLogger(MyExceptionHandler.class);
-
- @Override
- public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
- Exception ex) {
- Map<String,Object> map = new HashMap<String,Object>();
- logger.error(ex.getMessage(),ex);
- if(ex instanceof MaxUploadSizeExceededException){
- map.put("msg", "文件大小超过限制!");
- return new ModelAndView(new MappingJackson2JsonView(),map);
- }
- map.put("msg", "系统错误!");
- return new ModelAndView(new MappingJackson2JsonView(),map);
- }
- }
这个异常类里面, 我们打印了异常日志,并且对某种异常类型(这里是上传文件过大)做了特殊处理. 返回值这里用的是返回json格式的.
然后在配置文件(这里放在spring-mvc.xml)中将exceptionHandler指向我们自己写的类
- <bean id="exceptionHandler" class="com.dingcheng.common.exception.MyExceptionHandler"/>
就这么简单,就可以了.
2: 记录异常方法的参数名称和值
这大概分为2步, 首先拦截到controller的bean, 其次获取异常方法的参数
1)拦截controller
需要在spring-mvc.xml文件中配置spirng的aop:config,指定拦截的bean和用来处理拦截的类
- <bean id="paramAspect" class="com.dingcheng.common.aop.ParamAspect" />
- <aop:config>
- <aop:aspect id="exParamAspect" ref="paramAspect">
- <aop:pointcut id="exParam" expression="execution(* com.dingcheng.*.controller.*.*(..))" />
- <aop:after-throwing pointcut-ref="exParam" method="doThrowing" throwing="ex" />
- </aop:aspect>
- </aop:config>
这个aop配置要放在 spring-mvc里面,如果放在application-context.xml或者spring-mybatis.xml中可能不行.
这里配置了 aop:after-throwing, 用于方法抛出异常后调用, 当然也可以配置其他的 before,around等.
再来看看ParamAspect这个类
- public class ParamAspect {
- private Logger logger = Logger.getLogger(ParamAspect.class);
-
- public void doThrowing(JoinPoint jp, Throwable ex) {
-
- Signature signature = jp.getSignature();
- MethodSignature methodSignature = (MethodSignature) signature;
- String[] paramNameArr = methodSignature.getParameterNames();
-
-
- Object[] paramValueArr = jp.getArgs();
- StringBuilder sbd = new StringBuilder("pparam-->");
- for(int i=0;i<paramValueArr.length;i++){
- sbd.append(paramNameArr[i]+":"+paramValueArr[i]+",");
- }
- logger.error(sbd);
- }
- }
doThrowing方法对应aop:after-throwing里面配置的method.
2)获取异常方法的参数
上面的代码中,doThrowing方法里面已经实现了 获取异常方法参数名称和值的方法
3.测试下
- @RequestMapping(value = "add.action", method = RequestMethod.POST)
- public String list(Model model, String loginName,String password) {
- User user = new User();
- user.setLoginName(loginName);
- user.setPassword(password);
- userService.create(user);
- if(userService!=null){
- throw new RuntimeException("测试一下");
- }
- return "redirect:list.action";
- }
源码地址:https://code.youkuaiyun.com/qq315737546/ssmq/tree/master