SpringMVC中的异常处理集锦

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

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

时间: 11-21

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

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

我们知道,系统中异常包括:编译时异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试通过手段减少运行时异常的发生.在开发中,不管是dao层.service层还是controller层,都有可能抛出异常,在springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护.这篇博文主要总结一下SpringMVC中如何统一处理异常. 1. 异常处理思路 首先来看一下在spr

【SpringMVC学习11】SpringMVC中的拦截器

Springmvc的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理.本文主要总结一下springmvc中拦截器是如何定义的,以及测试拦截器的执行情况和使用方法. 1. springmvc拦截器的定义和配置 1.1 springmvc拦截器的定义 在springmvc中,定义拦截器要实现HandlerInterceptor接口,并实现该接口中提供的三个方法,如下: //测试拦截器1 public class HandlerInterceptor1 im

SpringMVC中文件上传的客户端验证

SpringMVC中文件上传的客户端验证 客户端验证主要思想:在jsp页面中利用javascript进行对文件的判断,完成验证后允许上传 验证步骤:1.文件名称 2.获取文件的后缀名称 3.判断哪些文件类型允许上传 4.判断文件大小 5.满足条件后跳转后台实现上传 前台界面(验证上传文件是否格式满足要求): <body> <h2>文件上传</h2> <form action="upload01" method="post" 

springmvc 中 Instantiation of bean failed实例化Bean失败错误

配置springMVC 项目时,启动tomcat服务器报错: 错误: 信息: Initializing Spring FrameworkServlet 'springmvc' 2015-8-19 9:57:35 org.apache.catalina.core.ApplicationContext log 严重: StandardWrapper.Throwable org.springframework.beans.factory.BeanCreationException: Error cre

项目中java异常处理

一.java异常类介绍. Throwable: 有两个重要的子类:Exception(异常)和 Error(错误),二者都是 Java 异常处理的重要子类,各自都包含大量子类. 有一篇比较好的blog,http://blog.csdn.net/hguisu/article/details/6155636 介绍java异常. 二.异常处理方式. 在 Java 应用程序中,异常处理机制为:抛出异常,捕捉异常. 三.程序中使用. 2种处理方式 1.throw new 异常  在方法体上写throws

第65课 C++中的异常处理(下)

1. C++中的异常处理 (1)catch语句块可以抛出异常 ①catch中获捕的异常可以被重新抛出 ②抛出的异常需要外层的try-catch块来捕获 ③catch(…)块中抛异常的方法是throw;也是将所有异常重新抛出 (2)catch块中重新抛异常的意义 ①可以被外层try-catch块捕获,并重新解释异常的信息. ②工程开发中使用这样的方式统一异常类型 A.假设我们的私有库使用到了第3方的库函数,如func. B.但其抛出的异常类型为int*类型,很不友好.我们可以在私有库使用func的

C++、Java、JavaScript中的异常处理(Exception)

编程思想之异常处理 什么叫异常处理? 什么叫异常(Exception)?顾名思义就是非正常的情况,出现了不希望出现的意外,异常处理就是遇到这种意外时准备的对策和解决方案.比如您开着一辆劳斯莱斯在公路上行走,突然前面出现一个小孩,幸好您眼疾手快紧急刹车,而避免了一场交通事故.在这个例子中突然出现的小孩就是异常,紧急刹车就是异常处理(面对这种突发情况采取的解决方案). 程序来源于现实,是现实的抽象和模拟,也会有异常,因此异常的处理就显示的极为重要.试想如果您的手机的某个应用使用两下就崩溃了,或都出现

Struts2中的异常处理

因为在Action的execute方法声明时就抛出了Exception异常,所以我们无需再execute方法中捕捉异常,仅需在struts.xml 中配置异常处理. 为了使用Struts2的异常处理机制,必须打开Struts2的异常映射功能,这需要exception拦截器.在struts-default.xml文件中已经开启了exception拦截器. 声明式异常捕捉 Struts2的异常处理机制是通过在struts.xml文件中配置<exception-mapping--/>元素完成的,配置

关于Springmvc中include与Sitemesh装饰器的基本使用

关于Springmvc中include与Sitemesh装饰器的使用 !!!转载请注明出处=>http://www.cnblogs.com/funnyzpc/p/7283443.html 静态包含:example:<%@include file="xxx.jsp"%> 文件的包含是发生在 jsp向servlet转换时期 ,相当于将jsp编译成html静态文件,由于对包含的文件不再编译(直接拷贝到父页面),则只产生一个class文件. 动态包含:example<j