spring mvc4:异常处理
前面学习过struts2的异常处理,今天来看下spring mvc4的异常处理:
一、Servlet配置文件修改
- <bean id="exceptionResolver"
- class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
- <property name="defaultErrorView" value="errors/error" />
- <property name="exceptionMappings">
- <props>
- <prop key="java.lang.Throwable">errors/error</prop>
- </props>
- </property>
- </bean>
增加上面这一节,大意是:只要有异常就跳到/WEB-INF/views/errors/error.jsp这个页面,当然如果要实现个性化的错误处理,比如:业务错误跳到页面A,SQL错误跳到页面B...,直接在props节点下,根据不同的异常类型,自行扩充 (注:404之类的错误,仍然参考struts2异常处理中的做法,在web.xml中配置解决)
二、创建一个BaseController基类,里面放一个以下方法:
- @ExceptionHandler
- public String exp(HttpServletRequest request, Exception ex) {
- String resultViewName = "errors/error";
- // 记录日志
- logger.error(ex.getMessage(), ex);
- // 根据不同错误转向不同页面
- if (ex instanceof BusinessException) {
- resultViewName = "errors/biz-error";
- } else {
- // 异常转换
- ex = new Exception("系统太累了,需要休息!");
- }
- request.setAttribute("ex", ex);
- return resultViewName;
- }
记录异常日志、根据不同的异常类型转到不同的处理页面、友好异常转换(如果需要的话),都在上面的方法中处理了
三、所有Controller都继承自BaseController
这个,就不解释了
四、error.jsp页面
- <%@ page contentType="text/html;charset=UTF-8" language="java"%>
- <%
- Exception e = (Exception) request.getAttribute("ex");
- %>
- <html>
- <head>
- <title>师傅,有妖怪:error</title>
- </head>
- <body>
- <H2>
- 错误:<%=e.getClass().getSimpleName()%></H2>
- <hr />
- <P>
- <strong>错误描述:</strong><%=e.getMessage()%>
- </P>
- <P>
- <strong>详细信息:</strong>
- </P>
- <pre>
- <%
- e.printStackTrace(new java.io.PrintWriter(out));
- %>
- </pre>
- </body>
- </html>
上面的内容只是示意,大家可以根据需要自行美化
另:前文struts2的异常处理中,采用的是拦截器思想,spring mvc中也有拦截器,而且拦截的点更灵活:
- package com.cnblogs.yjmyzz.interceptor;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
- import org.springframework.web.servlet.ModelAndView;
- import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
- public class ExcpetionInterceptor extends HandlerInterceptorAdapter {
- protected Logger logger = LogManager.getLogger();
- @Override
- public boolean preHandle(HttpServletRequest request,
- HttpServletResponse response, Object handler) throws Exception {
- System.out.println("ExcpetionInterceptor.preHandle");
- // 演示:限制仅允许从本机访问
- if (request.getLocalAddr().equals("127.0.0.1")
- || request.getLocalAddr().equals("0.0.0.0")) {
- return true;
- }
- logger.error("非法入侵:" + request.getLocalAddr());
- return false;
- }
- @Override
- public void postHandle(HttpServletRequest request,
- HttpServletResponse response, Object handler,
- ModelAndView modelAndView) throws Exception {
- System.out.println("ExcpetionInterceptor.postHandle");
- }
- @Override
- public void afterCompletion(HttpServletRequest request,
- HttpServletResponse response, Object handler, Exception ex)
- throws Exception {
- System.out.println("ExcpetionInterceptor.afterCompletion");
- if (ex != null) {
- logger.error(handler);
- logger.error(ex.getMessage(), ex);
- }
- }
- @Override
- public void afterConcurrentHandlingStarted(HttpServletRequest request,
- HttpServletResponse response, Object handler) throws Exception {
- System.out
- .println("ExcpetionInterceptor.afterConcurrentHandlingStarted");
- }
- }
拦截器创建后,依然要在servlet配置文件中注册:
- <mvc:interceptors>
- <bean class="com.cnblogs.yjmyzz.interceptor.ExcpetionInterceptor"></bean>
- </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:异常处理的更多相关文章
- Struts2、Spring MVC4 框架下的ajax统一异常处理
本文算是struts2 异常处理3板斧.spring mvc4:异常处理 后续篇章,普通页面出错后可以跳到统一的错误处理页面,但是ajax就不行了,ajax的本意就是不让当前页面发生跳转,仅局部刷新, ...
- Spring Boot异常处理详解
在Spring MVC异常处理详解中,介绍了Spring MVC的异常处理体系,本文将讲解在此基础上Spring Boot为我们做了哪些工作.下图列出了Spring Boot中跟MVC异常处理相关的类 ...
- Spring Boot 异常处理
Spring Boot 异常处理 本节介绍一下 Spring Boot 启动时是如何处理异常的?核心类是 SpringBootExceptionReporter 和 SpringBootExcepti ...
- Spring Boot异常处理
一.默认映射 我们在做Web应用的时候,请求处理过程中发生错误是非常常见的情况.Spring Boot提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局 ...
- Spring全局异常处理的三种方式
在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合度高,工作 ...
- Spring 全局异常处理
[参考文章]:Spring全局异常处理的三种方式 [参考文章]:Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理 [参考文章]:@ControllerAdvic ...
- Spring MVC异常处理SimpleMappingExceptionResolver
Spring MVC异常处理SimpleMappingExceptionResolver[转] (2012-12-07 13:45:33) 转载▼ 标签: 杂谈 分类: 技术分享 Spring3.0中 ...
- Spring统一异常处理
1.为什么要用Spring的统一异常处理? 项目中无论是controller层.service层还是dao层都会有异常发生.每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量 ...
- Spring Mvc4 新特性(一)
前言 Spring Framework的Web层,由spring-web,spring-webmvc,spring-websocket和spring-webmvc-portlet模块组成. 很多人刚学 ...
随机推荐
- Android进程管理及静态变量垃圾回收
1.Android静态变量的生命周期 静态变量的生命周期遵守Java的设计.我们知道静态变量是在类被load的时候分配内存的,并且存在于方法 区.当类被卸载的时候,静态变量被销毁. 在PC机的客户端程 ...
- CSS Float 以及相关布局模式
float 取值 属性 值 描述 left 向左浮动 right 向右浮动 none 默认值 inherit 继承 看一个栗子 红色线框代表父元素 脱离文档流,其实也没有完全脱离,会被 ...
- css控制标题长度超出部分显示省略号
width: 50px; overflow:hidden;white-space:nowrap; text-overflow:ellipsis; 设置或检索是否使用一个省略标记(...)标示对象内文本 ...
- CVEH项目观察与思考
2013-07-01 项目进展: 从启动至今已有三个星期,但是进展甚慢,取得的进展有: A. 封装成库,和HB调用库的接口有些进展,但进未完成 B. 整个框架,类视图,调用视图,只有两三层的进展: C ...
- mysql优化---订单查询优化:视图优化+索引创建
订单的表结构采用了垂直分表的策略,将订单相关的不同模块的字段维护在不同表中 在订单处理这个页面,需要查询各种维度, 因此为了方便查询创建了v_sale_order视图(老版本) drop view v ...
- Highcharts使用简例 + 异步动态读取数据
第一部分:在head之间加载两个JS库. <script src="html/js/jquery.js"></script> <script src= ...
- CCommandManager 类
CCommandManager类 CCommandManager 类管理命令及其与图像的关联.描述CCommandManager :: CleanUp从命令列表和全局和用户映射中删除所有元素.CCom ...
- 【JAVA小结】类的属性组的使用
public class UsingAttribute { static String strA = "string-a"; static String strB; static ...
- WD硬盘型号信息
买硬盘的时候有时候分不清 既然找到了就发上来吧
- 报表引擎API开发入门— EJB程序数据源
我们前面讲了几个数据源,今天我们来讲一下EJB数据源,这篇讲完我们数据源这部分就讲完了.数据连接不需要直接访问数据库,而是使用EJB做为数据源.FR通过定义程序数据集使用EJB的相关类获取到EJB数据 ...