一、概述

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. RelativeLayout设置wrap_content无效

    尊重劳动成果,转载请标明出处:http://www.cnblogs.com/tangZH/p/8419053.html 在做项目的过程中,遇到了一个奇怪的现象,我设置RelativeLayout为的宽 ...

  2. Git:八、Git自定义:忽略特殊文件&配置别名

    1..gitignore配置文件 1)防止加入Git或输入git status时显示,需要让Git忽略的文件: 程序编译生成的非原代码的文件 存放密码的文件 2)配置文件:.gitignore Git ...

  3. DVWA 黑客攻防演练(六)不安全的验证码 Insecure CAPTCHA

    之前在 CSRF 攻击 的那篇文章的最后,我觉得可以用验证码提高攻击的难度. 若有验证码的话,就比较难被攻击者利用 XSS 漏洞进行的 CSRF 攻击了,因为要识别验证码起码要调用api,跨域会被浏览 ...

  4. 07-Vue的基础使用

    vue的介绍 前端框架和库的区别 nodejs的简单使用 vue的起步 指令系统 组件的使用 过滤器的使用 watch和computed 钩子函数 渐进式的JavaScript框架 vue react ...

  5. Java文件输入保存,统计某个字符串,统计所有字符串

    import java.io.*; import java.util.*; /** * Created by Admin on 2018/3/20. */ public class FileSaveT ...

  6. c/c++浮点数在内存中存储方式

    转自:https://www.cnblogs.com/dolphin0520/archive/2011/10/02/2198280.html 任何数据在内存中都是以二进制的形式存储的,例如一个shor ...

  7. jQuery如何制作动画

    下面为一组图片(四张)展示 1 2 3 4 页面代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN& ...

  8. Codechef Bear and Clique Distances

    题目:Bear and Clique Distances 描述:共有N个点,前1—K个点任意两点之间有一条无向边,边的权值为X,再任意给M条边(u,v,w)(不重复),求任意一点到其余各点的最短路. ...

  9. Ubuntu composer 安装thinkphp5 失败,报错:[ErrorException] mkdir(): Permission denied

    在Linux环境下,使用composer安装thinkphp5,安装时,报错:[ErrorException]               mkdir(): Permission denied : 看 ...

  10. pymsql模块

    老师的博客地址:http://www.cnblogs.com/wupeiqi/articles/5713330.html 通过pymysql 模块可以通过朋友去操作mysql 数据库,首先的在pip上 ...