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模块组成. 很多人刚学 ...
随机推荐
- [修复Win8.1 BUG] 解决Win8.1英文字体发虚不渲染问题
Win8.1更新了宋体字体,中文字体显示漂亮了,但英文字体发虚不渲染,尤其是小号的英文和数字字体,看下图. 1.下载Win8的宋体2.打开字体文件点击安装3.导入注册表文件4.重启Win8.1 下载链 ...
- [译] MYSQL索引最佳实践
近日整理文档时发现多年前的这个文档还是蛮实用的,然后在网络搜索了一下并没有相关的译文,所以决定把它翻译过来,如有不当的地方请多包涵和指正.原文地址:https://www.percona.com/fi ...
- Redis客户端开发包:Jedis学习-高级应用
事务 Jedis中事务的写法是将redis操作写在事物代码块中,如下所示,multi与exec之间为具体的事务. jedis.watch (key1, key2, ...); Transaction ...
- Javascript 优化项目代码技巧之语言基础(二)
上一篇随笔介绍了如何正确判断对象类型.避免变量污染,特殊值(null.undefined.NaN)的使用,以及其他Javascript中常用关键字与方法的优化,这篇随笔将着重介绍Javascr ...
- Oracle BIEE启停脚本
作为BI的开发人员,经常启停BI服务在所难免,启动的过程又比较长,命令需要不同目录切换,简直烦死人呢, 特意整理了linux中的启动脚本,将以下脚本存成biee.sh,后面的过程就相当简单了, 启动: ...
- JavaScript Lib Interface (JavaScript系统定义的接口一览表)
function Object(){}; Object.prototype.toString = function(){return "";}; Object.prototype. ...
- OOP应用:实体类
实体类 定义:实体类是一个业务实体的类,而业务实体就是整个软件系统业务所涉及的对象. 使用: 1.新增实体类项目,增加类库项目,以.Modes作为后缀. 2.抽取对象以及属性.(简单地说,对象就是每个 ...
- (企业面试部分)超详细思路讲解SQL语句的查询实现,及数据的创建。
企业面试部分详细的SQL问题,思路讲解 第一步:创建数据库表,及插入数据信息 --Student(S#,Sname,Sage,Ssex) 学生表 CREATE TABLE student( sno ) ...
- Sql server之sql注入篇
SQL Injection 关于sql注入的危害在这里就不多做介绍了,相信大家也知道其中的厉害关系.这里有一些sql注入的事件大家感兴趣可以看一下 防范sql注入的方法无非有以下几种: 1.使用类型安 ...
- C#调用自定义表类型参数
-SQL SERVER生成测试环境: --创建测试DB CREATE database Sales; go USE Sales GO --创建表类型 IF TYPE_ID('LocalDT') IS ...