1 描述 
在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。 
那么,能不能将所有类型的异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护?答案是肯定的。下面将介绍使用Spring MVC统一处理异常的解决和实现过程。 
2 分析 
Spring MVC处理异常常见有4种方式: 
(1)使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver; 
(2)实现Spring的异常处理SimpleMappingExceptionResolver自定义自己的异常处理器;

(3)实现HandlerExceptionResolver 接口自定义异常处理器 
(4)使用注解@ExceptionHandler实现异常处理;

3 实战

一:使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver

源码介绍:

1.lib包(jar包)和web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<display-name></display-name>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

2.index.jsp(测试页面入口)和 error.jsp(有错误则会跳到此页面)和 hello.jsp(没错误则会跳到此页面)

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>"> <title>异常处理器测试</title>
</head>
<body>
<form action="frist.do" method="post">
<input type="submit" value="测试" />
</form>
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>这是错误页面</title>
</head>
<body>
这是错误页面 ${ex.message }
</body>
</html>
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>成功欢迎页面</title>
</head>
<body>
你竟然没报错<br/>
</body>
</html>

3.MyController,java(定义自己的处理器)

package cn.zhang.controller;
//定义自己的处理器
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; @Controller
public class MyController{ @RequestMapping(value="/frist.do",produces="text/html;charset=utf-8",method=RequestMethod.POST)
public String frist(){
//制造一个异常
int i=5/0;
System.out.println(i);
return "forward:/hello.jsp";
}
}

4.applicationContext.xml(Spring的配置文件)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 使用注解方式完成映射 -->
<context:component-scan base-package="cn.zhang.controller"></context:component-scan>
<!-- mvc的注解驱动 -->
<mvc:annotation-driven />
<!-- 注册系统异常处理器 -->
<bean
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error.jsp"></property>
<property name="exceptionAttribute" value="ex"></property>
</bean> </beans>

测试展示:

点击测试,由于我们在自己的处理器制造了一个异常,所以它会跳到错误页面

二:实现Spring的异常处理接口SimpleMappingExceptionResolver自定义自己的异常处理器

源码介绍:

1.lib包和web.xml一样(不做解释)

2.error包中是指定错误页面

ageerrors.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>年龄错误页面</title>
</head>
<body>年龄错误 ${ex.message }
</body>
</html>

nameerrors.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>名字错误页面</title>
</head>
<body>
名字错误
${ex.message }
</body>
</html>

3.MyController.java

package cn.zhang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.zhang.exception.AgeException;
import cn.zhang.exception.NameException;
import cn.zhang.exception.UserException; //定义自己的处理器 @Controller
public class MyController{ @RequestMapping(value="/frist.do")
public String frist(Model model,String name,int age) throws UserException{
if (name.equals("admin")) {
throw new NameException("用户名错误");
}
if (age>50) {
throw new AgeException("年龄过大");
}
return "forward:/hello.jsp";
}
}

4.exception包下,指定我们的异常类

UserException.java

package cn.zhang.exception;
//定义UserException继承Exception
public class UserException extends Exception { private static final long serialVersionUID = 1L; public UserException() {
super();
// TODO Auto-generated constructor stub
} public UserException(String message) {
super(message);
// TODO Auto-generated constructor stub
} }

AgeException.java

package cn.zhang.exception;
//继承UserException父类
public class AgeException extends UserException { private static final long serialVersionUID = 1L; public AgeException() {
super();
// TODO Auto-generated constructor stub
} public AgeException(String message) {
super(message);
// TODO Auto-generated constructor stub
} }

NameException.java

package cn.zhang.exception;
//继承UserException父类
public class NameException extends UserException { private static final long serialVersionUID = 1L; public NameException() {
super();
// TODO Auto-generated constructor stub
} public NameException(String message) {
super(message);
// TODO Auto-generated constructor stub
} }

5.applicationContext.xml(Spring的配置文件)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 使用注解方式完成映射 -->
<context:component-scan base-package="cn.zhang.controller"></context:component-scan>
<!-- mvc的注解驱动 -->
<mvc:annotation-driven />
<!-- 实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器 -->
<bean
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error.jsp"></property>
<property name="exceptionAttribute" value="ex"></property>
<!-- 指定错误到指定页面 -->
<property name="exceptionMappings">
<props>
<prop key="cn.zhang.exception.AgeException">error/ageerrors.jsp</prop>
<prop key="cn.zhang.exception.NameException">error/nameerrors.jsp</prop>
</props>
</property> </bean> </beans>

结果展示:

 三:实现HandlerExceptionResolver 接口自定义异常处理器 

要修改的代码:

1.MyHandlerExceptionResolver.java--定义自己的异常处理器(实现HandlerExceptionResolver接口)

package cn.zhang.resolvers;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import cn.zhang.exception.AgeException;
import cn.zhang.exception.NameException;
/**
* 定义自己的异常处理器(实现HandlerExceptionResolver接口)
* @author zhangzong
*
*/
public class MyHandlerExceptionResolver implements HandlerExceptionResolver{ public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) { ModelAndView mv=new ModelAndView();
mv.addObject("ex",ex); mv.setViewName("/errors.jsp"); if(ex instanceof NameException){
mv.setViewName("/error/nameerrors.jsp");
} if(ex instanceof AgeException){
mv.setViewName("/error/ageerrors.jsp");
} return mv;
} }

2.applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 使用注解方式完成映射 -->
<context:component-scan base-package="cn.zhang.controller"></context:component-scan>
<!-- mvc的注解驱动 -->
<mvc:annotation-driven />
<!-- 注册自定义异常处理器 -->
<bean class="cn.zhang.resolvers.MyHandlerExceptionResolver"/>
</beans>

其他的相同,不作解释

 四:使用注解@ExceptionHandler实现异常处理

源码介绍:

1.其他配置相同(不做解释)

2.MyController.java--继承我们自己定义的注解异常处理器MyHandlerExceptionResolver

package cn.zhang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.zhang.exception.AgeException;
import cn.zhang.exception.NameException;
import cn.zhang.exception.UserException;
import cn.zhang.resolvers.MyHandlerExceptionResolver; //定义自己的处理器
//继承我们自己定义的注解异常处理器MyHandlerExceptionResolver
@Controller
public class MyController extends MyHandlerExceptionResolver{ @RequestMapping(value="/frist.do")
public String frist(Model model,String name,int age) throws UserException{
if (name.equals("admin")) {
throw new NameException("用户名错误");
}
if (age>50) {
throw new AgeException("年龄过大");
}
return "forward:/hello.jsp";
}
}

3.MyHandlerExceptionResolver.java--定义自己的异常处理器(使用注解)

package cn.zhang.resolvers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
import cn.zhang.exception.AgeException;
import cn.zhang.exception.NameException;
/**
* 定义自己的异常处理器(使用注解)
* @author zhangzong
*
*/
@Controller
public class MyHandlerExceptionResolver{ @ExceptionHandler
public ModelAndView resolveException(Exception ex) { ModelAndView mv=new ModelAndView();
mv.addObject("ex",ex); mv.setViewName("/errors.jsp"); if(ex instanceof NameException){
mv.setViewName("/error/nameerrors.jsp");
} if(ex instanceof AgeException){
mv.setViewName("/error/ageerrors.jsp");
} return mv;
} }

4.applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 使用注解方式完成映射 -->
<context:component-scan base-package="cn.zhang.controller"></context:component-scan>
<!-- mvc的注解驱动 -->
<mvc:annotation-driven /> <!-- 注册自定义异常处理器 -->
<bean class="cn.zhang.resolvers.MyHandlerExceptionResolver"/>
</beans>

效果和上相同,这里不做展示

SpringMVC中的异常处理集锦的更多相关文章

  1. SpringMVC 中的异常处理

    目录 1.搭建编码分析 2.编写异常类 3.编写自定义异常处理器 4.在springmvc.xml中配置异常处理器 5.编写Error.jsp.index.jsp页面 6.编写collector代码模 ...

  2. SpringMVC中的异常处理

    springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑. 1. 异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeExc ...

  3. springmvc中的异常处理方法

    //1.自定义异常处理类       2.编写异常处理器    3.配置异常处理器 package com.hope.exception;/** * 异常处理类 * @author newcityma ...

  4. SpringMVC中的 --- 异常处理

    系统异常处理器SimpleMappingExceptionResolver 处理器方法执行过程中,可能会发生异常,不想看到错误黄页,想看到一个友好的错误提示页. 自定义异常处理器 使用异常处理注解

  5. 【SpringMVC学习07】SpringMVC中的统一异常处理

    我们知道,系统中异常包括:编译时异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试通过手段减少运行时异常的发生.在开发中,不管是dao层 ...

  6. (转)SpringMVC学习(八)——SpringMVC中的异常处理器

    http://blog.csdn.net/yerenyuan_pku/article/details/72511891 SpringMVC在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常 ...

  7. JavaEE开发之SpringMVC中的自定义拦截器及异常处理

    上篇博客我们聊了<JavaEE开发之SpringMVC中的路由配置及参数传递详解>,本篇博客我们就聊一下自定义拦截器的实现.以及使用ModelAndView对象将Controller的值加 ...

  8. springmvc中Controller前端控制器的映射与返回数据,以及异常处理

    .@RequestMapping映射 该注解中存的是映射路径的字符串 1.1 value的值是一个数组,也就是说可以定义多个访问路径,同时“.action”可以省略,前端控制器中主要查找主体部分.注意 ...

  9. springmvc 中异常处理

    springmvc 中异常处理常见三种处理方式: 1:SimpleMappingExceptionResolver处理的是处理器方法里面出现的异常 2 3.自定义异常处理器:处理的是处理器方法里面出现 ...

随机推荐

  1. [ASP.NET MVC 小牛之路]18 - Web API

    Web API 是ASP.NET平台新加的一个特性,它可以简单快速地创建Web服务为HTTP客户端提供API.Web API 使用的基础库是和一般的MVC框架一样的,但Web API并不是MVC框架的 ...

  2. 測試大型資料表的 Horizontal Partitioning 水平切割

    FileGroup 檔案群組 :一個「資料庫(database)」可對應一或多個 FileGroup,一個 FileGroup 可由一或多個 file (.ndf) 構成. FileGroup 可讓 ...

  3. IE浏览器打开chorme浏览器,如何打开其他浏览器

    看到这个标题是否感觉奇怪,为什么要用IE浏览器打开chorme或者火狐浏览器等,这个功能从开发者来说不是一个好的需求,但确实是真实存在的,有用公司的背景历史比较复杂,而且公司有过长期的开发历史,这导致 ...

  4. RequireJS学习笔记

    前言 进入移动前端是很不错的选择,这块也是我希望的道路,但是不熟悉啊... 现在项目用的是require+backbone,整个框架被封装了一次,今天看了代码搞不清楚,觉得应该先从源头抓起,所以再看看 ...

  5. JavaScript中闭包之浅析解读

    JavaScript中的闭包真心是一个老生常谈的问题了,最近面试也是一直问到,我自己的表述能力又不能完全支撑起来,真是抓狂.在回来的路上,我突然想到了一个很简单的事情,其实我们在做项目时候,其实就经常 ...

  6. MongoDB 使用Index

    Index 能够提高查询的性能,如果没有Index,MongoDB必须扫描整个collection,从collection的第一个doc开始,直到最后一个doc,即使第一个doc之后的所有doc都不满 ...

  7. SQL 笔记 By 华仔

    -------------------------------------读书笔记------------------------------- 笔记1-徐 最常用的几种备份方法 笔记2-徐 收缩数据 ...

  8. SQL Server游标

    什么是游标 结果集,结果集就是select查询之后返回的所有行数据的集合. 游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据 ...

  9. Git-Notes

    1.Git安装,直接在官网下载安装即可. 2.Git配置,使用config选项,配置名字和邮箱,如下所示 C:\Users\1yyg>git config --global user.name ...

  10. 使用nginx解决跨域问题(flask为例)

    背景 我们单位的架构是在api和js之间架构一个中间层(python编写),以实现后端渲染,登录状态判定,跨域转发api等功能.但是这样一个中间会使前端工程师的工作量乘上两倍,原本js可以直接ajax ...