你的位置:首页 > Java教程

[Java教程]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.

<??><web-app ="http://www.w3.org/2001/ ="http://java.sun.com/ ="http://java.sun.com/ xsi:schemaLocation="http://java.sun.com/ 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.</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>

View Code

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>

View Code
<%@ 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>

View Code
<%@ 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>

View Code

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;@Controllerpublic 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";  }}

View Code

4.applicationContext.

<??><beans ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context"  ="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>

View Code

测试展示:

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

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

源码介绍:

1.lib包和web.

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>

View Code

  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>

View Code

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;//定义自己的处理器@Controllerpublic 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";  }}

View Code

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

 UserException.java

package cn.zhang.exception;//定义UserException继承Exceptionpublic 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  }  }

View Code

 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  }    }

View Code

 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  }}

View Code

5.applicationContext.

<??><beans ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context"  ="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>

View Code

结果展示:

 三:实现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;  }  }

View Code

 2.applicationContext.

<??><beans ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context"  ="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>

View Code

 其他的相同,不作解释

 四:使用注解@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@Controllerpublic 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";  }}

View Code

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 * */@Controllerpublic 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;  }  }

View Code

4.applicationContext.

<??><beans ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/ ="http://www.springframework.org/schema/context"  ="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>

View Code

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