前面学习过struts2的异常处理,今天来看下spring mvc4的异常处理:

一、Servlet配置文件修改

  1. <bean id="exceptionResolver"
  2. class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  3. <property name="defaultErrorView" value="errors/error" />
  4. <property name="exceptionMappings">
  5. <props>
  6. <prop key="java.lang.Throwable">errors/error</prop>
  7. </props>
  8. </property>
  9. </bean>

增加上面这一节,大意是:只要有异常就跳到/WEB-INF/views/errors/error.jsp这个页面,当然如果要实现个性化的错误处理,比如:业务错误跳到页面A,SQL错误跳到页面B...,直接在props节点下,根据不同的异常类型,自行扩充 (注:404之类的错误,仍然参考struts2异常处理中的做法,在web.xml中配置解决)

二、创建一个BaseController基类,里面放一个以下方法:

  1. @ExceptionHandler
  2. public String exp(HttpServletRequest request, Exception ex) {
  3. String resultViewName = "errors/error";
  4.  
  5. // 记录日志
  6. logger.error(ex.getMessage(), ex);
  7.  
  8. // 根据不同错误转向不同页面
  9. if (ex instanceof BusinessException) {
  10. resultViewName = "errors/biz-error";
  11. } else {
  12. // 异常转换
  13. ex = new Exception("系统太累了,需要休息!");
  14. }
  15. request.setAttribute("ex", ex);
  16. return resultViewName;
  17. }

记录异常日志、根据不同的异常类型转到不同的处理页面、友好异常转换(如果需要的话),都在上面的方法中处理了

三、所有Controller都继承自BaseController

这个,就不解释了

四、error.jsp页面

  1. <%@ page contentType="text/html;charset=UTF-8" language="java"%>
  2. <%
  3. Exception e = (Exception) request.getAttribute("ex");
  4. %>
  5. <html>
  6. <head>
  7. <title>师傅,有妖怪:error</title>
  8. </head>
  9. <body>
  10. <H2>
  11. 错误:<%=e.getClass().getSimpleName()%></H2>
  12. <hr />
  13. <P>
  14. <strong>错误描述:</strong><%=e.getMessage()%>
  15. </P>
  16.  
  17. <P>
  18. <strong>详细信息:</strong>
  19. </P>
  20. <pre>
  21. <%
  22. e.printStackTrace(new java.io.PrintWriter(out));
  23. %>
  24. </pre>
  25. </body>
  26. </html>

上面的内容只是示意,大家可以根据需要自行美化

另:前文struts2的异常处理中,采用的是拦截器思想,spring mvc中也有拦截器,而且拦截的点更灵活:

  1. package com.cnblogs.yjmyzz.interceptor;
  2.  
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5.  
  6. import org.apache.logging.log4j.LogManager;
  7. import org.apache.logging.log4j.Logger;
  8. import org.springframework.web.servlet.ModelAndView;
  9. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
  10.  
  11. public class ExcpetionInterceptor extends HandlerInterceptorAdapter {
  12.  
  13. protected Logger logger = LogManager.getLogger();
  14.  
  15. @Override
  16. public boolean preHandle(HttpServletRequest request,
  17. HttpServletResponse response, Object handler) throws Exception {
  18. System.out.println("ExcpetionInterceptor.preHandle");
  19. // 演示:限制仅允许从本机访问
  20. if (request.getLocalAddr().equals("127.0.0.1")
  21. || request.getLocalAddr().equals("0.0.0.0")) {
  22. return true;
  23. }
  24. logger.error("非法入侵:" + request.getLocalAddr());
  25. return false;
  26. }
  27.  
  28. @Override
  29. public void postHandle(HttpServletRequest request,
  30. HttpServletResponse response, Object handler,
  31. ModelAndView modelAndView) throws Exception {
  32. System.out.println("ExcpetionInterceptor.postHandle");
  33. }
  34.  
  35. @Override
  36. public void afterCompletion(HttpServletRequest request,
  37. HttpServletResponse response, Object handler, Exception ex)
  38. throws Exception {
  39. System.out.println("ExcpetionInterceptor.afterCompletion");
  40. if (ex != null) {
  41. logger.error(handler);
  42. logger.error(ex.getMessage(), ex);
  43. }
  44. }
  45.  
  46. @Override
  47. public void afterConcurrentHandlingStarted(HttpServletRequest request,
  48. HttpServletResponse response, Object handler) throws Exception {
  49. System.out
  50. .println("ExcpetionInterceptor.afterConcurrentHandlingStarted");
  51. }
  52.  
  53. }

拦截器创建后,依然要在servlet配置文件中注册:

  1. <mvc:interceptors>
  2. <bean class="com.cnblogs.yjmyzz.interceptor.ExcpetionInterceptor"></bean>
  3. </mvc:interceptors>

spring mvc的拦截器提供了4个处理方法:

preHandle在Controller被调用前,先执行,可以在这里执行一些安全检查(上面示意了如何对IP做限制)

postHandle在Controller调用后执行,这时,可以修改ModelAndView,比如转到其它view之类

afterCompletion在Controller调用全部完成后执行,如果ex变量不为空,表示有异常了,这里可以记录异常日志

afterConcurrentHandlingStarted这个没怎么研究过,暂时不做评价

值得一提的是:spring-mvc中的拦截器,虽然可以在afterCompletion中记录异常日志,但如果按前面的baseController配合@ExceptionHandler做了处理,这里的ex就变成了null,因为异常在前面已经得到了处理,所以这二种方法不推荐混用,另外afterCompletion方法中,如果要根据不同的异常类型转到不同处理页面,并不方便。

附:ajax的统一异常处理,请移步 Struts2、Spring MVC4 框架下的ajax统一异常处理

spring mvc4:异常处理的更多相关文章

  1. Struts2、Spring MVC4 框架下的ajax统一异常处理

    本文算是struts2 异常处理3板斧.spring mvc4:异常处理 后续篇章,普通页面出错后可以跳到统一的错误处理页面,但是ajax就不行了,ajax的本意就是不让当前页面发生跳转,仅局部刷新, ...

  2. Spring Boot异常处理详解

    在Spring MVC异常处理详解中,介绍了Spring MVC的异常处理体系,本文将讲解在此基础上Spring Boot为我们做了哪些工作.下图列出了Spring Boot中跟MVC异常处理相关的类 ...

  3. Spring Boot 异常处理

    Spring Boot 异常处理 本节介绍一下 Spring Boot 启动时是如何处理异常的?核心类是 SpringBootExceptionReporter 和 SpringBootExcepti ...

  4. Spring Boot异常处理

    一.默认映射 我们在做Web应用的时候,请求处理过程中发生错误是非常常见的情况.Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局 ...

  5. Spring全局异常处理的三种方式

    在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合度高,工作 ...

  6. Spring 全局异常处理

    [参考文章]:Spring全局异常处理的三种方式 [参考文章]:Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理 [参考文章]:@ControllerAdvic ...

  7. Spring MVC异常处理SimpleMappingExceptionResolver

    Spring MVC异常处理SimpleMappingExceptionResolver[转] (2012-12-07 13:45:33) 转载▼ 标签: 杂谈 分类: 技术分享 Spring3.0中 ...

  8. Spring统一异常处理

    1.为什么要用Spring的统一异常处理? 项目中无论是controller层.service层还是dao层都会有异常发生.每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量 ...

  9. Spring Mvc4 新特性(一)

    前言 Spring Framework的Web层,由spring-web,spring-webmvc,spring-websocket和spring-webmvc-portlet模块组成. 很多人刚学 ...

随机推荐

  1. Android进程管理及静态变量垃圾回收

    1.Android静态变量的生命周期 静态变量的生命周期遵守Java的设计.我们知道静态变量是在类被load的时候分配内存的,并且存在于方法 区.当类被卸载的时候,静态变量被销毁. 在PC机的客户端程 ...

  2. CSS Float 以及相关布局模式

    float 取值 属性 值 描述   left 向左浮动   right 向右浮动   none 默认值   inherit 继承 看一个栗子 红色线框代表父元素 脱离文档流,其实也没有完全脱离,会被 ...

  3. css控制标题长度超出部分显示省略号

    width: 50px; overflow:hidden;white-space:nowrap; text-overflow:ellipsis; 设置或检索是否使用一个省略标记(...)标示对象内文本 ...

  4. CVEH项目观察与思考

    2013-07-01 项目进展: 从启动至今已有三个星期,但是进展甚慢,取得的进展有: A. 封装成库,和HB调用库的接口有些进展,但进未完成 B. 整个框架,类视图,调用视图,只有两三层的进展: C ...

  5. mysql优化---订单查询优化:视图优化+索引创建

    订单的表结构采用了垂直分表的策略,将订单相关的不同模块的字段维护在不同表中 在订单处理这个页面,需要查询各种维度, 因此为了方便查询创建了v_sale_order视图(老版本) drop view v ...

  6. Highcharts使用简例 + 异步动态读取数据

    第一部分:在head之间加载两个JS库. <script src="html/js/jquery.js"></script> <script src= ...

  7. CCommandManager 类

    CCommandManager类 CCommandManager 类管理命令及其与图像的关联.描述CCommandManager :: CleanUp从命令列表和全局和用户映射中删除所有元素.CCom ...

  8. 【JAVA小结】类的属性组的使用

    public class UsingAttribute { static String strA = "string-a"; static String strB; static ...

  9. WD硬盘型号信息

    买硬盘的时候有时候分不清 既然找到了就发上来吧

  10. 报表引擎API开发入门— EJB程序数据源

    我们前面讲了几个数据源,今天我们来讲一下EJB数据源,这篇讲完我们数据源这部分就讲完了.数据连接不需要直接访问数据库,而是使用EJB做为数据源.FR通过定义程序数据集使用EJB的相关类获取到EJB数据 ...