一、概述

Spring MVC异常处理功能的作用为:捕捉处理器的异常,并映射到相应视图

有4种方式:

  • SimpleMappingExceptionResolver:通过配置的方式实现异常处理,该方式简单、无侵入性,但仅能获取到异常信息
  • HandlerExceptionResolver:通过实现该接口并实例化为bean实现异常处理,该方式简单、无侵入性,并能够获取关于异常的更详细信息
  • @ExceptionHandler:通过在控制器类或控制器类的基类中添加异常处理方法,从而实现单个控制器范围的异常处理,该方法对已有代码有侵入性
  • web.xml的<error-page>标签:可通过异常类型或error-code指定异常页面

多种方式的并存会增大维护的成本,因此异常处理方式选择其中一种,推荐使用SimpleMappingExceptionResolver,再配合web.xml中的<error-page>即可

简单示例:

异常类

public class BusinessException extends RuntimeException {

    private String errorCode;

    public BusinessException(String errorCode, String msg) {
super(msg);
this.setErrorCode(errorCode);
} public String getErrorCode() {
return errorCode;
} public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
}
public class ParameterException extends RuntimeException {

    public ParameterException(String msg) {
super(msg);
}
}

控制器

@Controller
public class TestController9 { @RequestMapping(value = "/controller.do", method = RequestMethod.GET)
public void controller(HttpServletResponse response, Integer id) throws Exception {
switch(id) {
case 1:
throw new BusinessException("10", "controller10");
case 2:
throw new BusinessException("20", "controller20");
default:
throw new ParameterException("Controller Parameter Error");
}
}
}

配置

<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 定义默认的异常处理页面 -->
<property name="defaultErrorView" value="error"></property>
<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
<property name="exceptionAttribute" value="ex"></property>
<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常页名作为值 -->
<property name="exceptionMappings">
<props>
<prop key="cn.matt.exception.BusinessException">error-business</prop>
<prop key="cn.matt.exception.ParameterException">error-parameter</prop>
</props>
</property>
</bean> <context:component-scan base-package="cn.matt" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController" />
</context:component-scan>
</beans>

error.jsp、error-business.jsp、error-parameter.jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<html>
<head><title>Exception!</title></head>
<body>
<% Exception e = (Exception)request.getAttribute("ex"); %>
<H2>业务错误: <%= e.getClass().getSimpleName()%></H2>
<hr />
<P>错误描述:</P>
<%= e.getMessage()%>
<P>错误信息:</P>
<% e.printStackTrace(new java.io.PrintWriter(out)); %>
</body>
</html>

启动后,访问 http://localhost:8080/myweb/controller.do?id=1 即可验证

二、SimpleMappingExceptionResolver

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<!-- 定义默认的异常处理页面,当该异常类型的注册时使用 -->
<property name="defaultErrorView" value="error"></property>
<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->
<property name="exceptionAttribute" value="ex"></property>
<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常也页名作为值 -->
<property name="exceptionMappings">
<props>
<prop key="cn.matt.exception.BusinessException">error-business</prop>
<prop key="cn.matt.exception.ParameterException">error-parameter</prop> <!-- 这里还可以继续扩展对不同异常类型的处理 -->
</props>
</property>
</bean>

使用SimpleMappingExceptionResolver进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,但该方法仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适用

具体如上例

三、HandlerExceptionResolver

@Component
public class MyExceptionHandler implements HandlerExceptionResolver { public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("ex", ex); // 根据不同错误转向不同页面
if(ex instanceof BusinessException) {
return new ModelAndView("error-business", model);
}else if(ex instanceof ParameterException) {
return new ModelAndView("error-parameter", model);
} else {
return new ModelAndView("error", model);
}
}
}

使用实现HandlerExceptionResolver接口的异常处理器进行异常处理,具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,同时,在异常处理时能获取导致出现异常的对象,有利于提供更详细的异常处理信息。

测试方式为:在上例配置文件中注释掉SimpleMappingExceptionResolver的配置,并添加HandlerExceptionResolver的上述代码即可

四、@ExceptionHandler

@Controller
public class TestController9 { @RequestMapping(value = "/controller.do", method = RequestMethod.GET)
public void controller(HttpServletResponse response, Integer id) throws Exception {
switch(id) {
case 1:
throw new BusinessException("10", "controller10");
case 2:
throw new BusinessException("20", "controller20");
default:
throw new ParameterException("Controller Parameter Error");
}
} @ExceptionHandler
public String exp(HttpServletRequest request, Exception ex) { request.setAttribute("ex", ex); // 根据不同错误转向不同页面
if(ex instanceof BusinessException) {
return "error-business";
}else if(ex instanceof ParameterException) {
return "error-parameter";
} else {
return "error";
}
}
}

使用@ExceptionHandler注解实现异常处理,具有集成简单、扩展性好、不需要附加Spring配置等优点,但该方法对已有代码存在入侵性,在异常处理时不能获取除异常以外的数据。

测试方式为:在上例配置文件中注释掉SimpleMappingExceptionResolver的配置,并将控制器修改为上述代码即可

五、web.xml的<error-page>标签

对于非控制器产生的异常,如404,spring mvc的异常机制无法捕获,此类异常可在web.xml中通过<error-page>节点配置显示页面

<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/500.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>

补充:

异常输出为json字符串(而非页面)的方式如下:

@ExceptionHandler
public void exp(HttpServletRequest request, HttpServletResponse response, Exception ex) throws IOException { response.setContentType("text/plain;charset=UTF-8");
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0); Map<String, Object> map = new HashMap<String, Object>();
map.put("errorCode", 200);
map.put("errorMsg", ex.getMessage());
response.getWriter().write(JSON.toJSONString(map));
}

参考:

使用Spring MVC统一异常处理实战

springmvc处理异常的4种方式

Spring MVC 异常处理详解

Spring MVC 使用介绍(九)—— 异常处理的更多相关文章

  1. Spring MVC 使用介绍(十五)数据验证 (二)依赖注入与方法级别验证

    一.概述 JSR-349 (Bean Validation 1.1)对数据验证进一步进行的规范,主要内容如下: 1.依赖注入验证 2.方法级别验证 二.依赖注入验证 spring提供BeanValid ...

  2. Spring MVC 使用介绍(十四)文件上传下载

    一.概述 文件上传时,http请求头Content-Type须为multipart/form-data,有两种实现方式: 1.基于FormData对象,该方式简单灵活 2.基于<form> ...

  3. Spring MVC 使用介绍(十三)数据验证 (一)基本介绍

    一.消息处理功能 Spring提供MessageSource接口用于提供消息处理功能: public interface MessageSource { String getMessage(Strin ...

  4. Spring MVC 使用介绍(十二)控制器返回结果统一处理

    一.概述 在为前端提供http接口时,通常返回的数据需要统一的json格式,如包含错误码和错误信息等字段. 该功能的实现有四种可能的方式: AOP 利用环绕通知,对包含@RequestMapping注 ...

  5. Spring MVC 使用介绍(五)—— 注解式控制器(一):基本介绍

    一.hello world 相对于基于Controller接口的方式,基于注解方式的配置步骤如下: HandlerMapping 与HandlerAdapter 分别配置为RequestMapping ...

  6. Spring MVC 使用介绍(八)—— 类型转换

    一.概述 spring类型转换有两种方式: PropertyEditor:可实现String<--->Object 之间相互转换 Converter:可实现任意类型的相互转换 类型转换的过 ...

  7. spring mvc简单介绍xml版

    spring mvc介绍:其实spring mvc就是基于servlet实现的,只不过他讲请求处理的流程分配的更细致而已. spring mvc核心理念的4个组件: 1.DispatcherServl ...

  8. Spring MVC 原理介绍(执行流程)

    Spring MVC工作流程图   图一   图二    Spring工作流程描述       1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServle ...

  9. Spring MVC 简单介绍

    Spring MVC 是典型的mvc架构,适合web开发. controler 输入输出的控制器,也是对外view提供数据的接口,调用service层. model 数据,由bean组成(相应表),关 ...

随机推荐

  1. Linux基础学习(全)

    使用的Linux发行版本为Redhat 1.Linux(RedHat)基础学习-命令行使用入门 2.Linux(RedHat)基础学习-文件寻址与管理 3.Linux(RadHat)基础学习-vim编 ...

  2. vue中如何使用mockjs摸拟接口的各种数据

    mockjs的作用 生成模拟数据 模拟 Ajax 请求,返回模拟数据 基于 HTML 模板生成模拟数据(后续更新) 帮助编写单元测试(后续更新) Vue 中使用 mock 有两种使用方式,一种是仅编写 ...

  3. 四大机器学习编程语言对比:R、Python、MATLAB、Octave

    本文作者是一位机器学习工程师,他比较了四种机器学习编程语言(工具):R.Python.MATLAB 和 OCTAVE.作者列出了这些语言(工具)的优缺点,希望对想开始学习它们的人有用. 图源:Pixa ...

  4. ArcGIS Server较早版本切片迁移注意事项

    原创文章,转载须标明出处自: http://www.cnblogs.com/gisspace/p/8286838.html -------------------------------------- ...

  5. git清空版本记录

    在网上找的,记录下来自己使用 1.新增分支 git checkout --orphan latest_branch 2. 添加问题 git add -A 3. 提交 git commit -am &q ...

  6. Maven替换为国内仓库

    <mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name&g ...

  7. selenium-确定找到的element唯一(三)

    在python + selenium 中经常会遇到找到的元素不唯一,导致定位到的元素不是预期的或者定位不到元素 解决方法:只要在页面进行确认找到的元素唯一后,再进行操作 页面确认方法: 1.通过htm ...

  8. linux kernel内存碎片防治技术

    Linux kernel组织管理物理内存的方式是buddy system(伙伴系统),而物理内存碎片正式buddy system的弱点之一,为了预防以及解决碎片问题,kernel采取了一些实用技术,这 ...

  9. Page Cache与Page回写

    综述 Page cache是通过将磁盘中的数据缓存到内存中,从而减少磁盘I/O操作,从而提高性能.此外,还要确保在page cache中的数据更改时能够被同步到磁盘上,后者被称为page回写(page ...

  10. C# -- 结构、访问修饰符

    C# -- 结构.访问修饰符 1. 结构: struct 类型 对于结构,不像类那样存在继承. 一个结构不能从另一个结构或类继承,而且不能作为一个类的基. 但是,结构从基类 Object 继承. 结构 ...