Spring MVC 使用介绍(九)—— 异常处理
一、概述
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 使用介绍(九)—— 异常处理的更多相关文章
- Spring MVC 使用介绍(十五)数据验证 (二)依赖注入与方法级别验证
一.概述 JSR-349 (Bean Validation 1.1)对数据验证进一步进行的规范,主要内容如下: 1.依赖注入验证 2.方法级别验证 二.依赖注入验证 spring提供BeanValid ...
- Spring MVC 使用介绍(十四)文件上传下载
一.概述 文件上传时,http请求头Content-Type须为multipart/form-data,有两种实现方式: 1.基于FormData对象,该方式简单灵活 2.基于<form> ...
- Spring MVC 使用介绍(十三)数据验证 (一)基本介绍
一.消息处理功能 Spring提供MessageSource接口用于提供消息处理功能: public interface MessageSource { String getMessage(Strin ...
- Spring MVC 使用介绍(十二)控制器返回结果统一处理
一.概述 在为前端提供http接口时,通常返回的数据需要统一的json格式,如包含错误码和错误信息等字段. 该功能的实现有四种可能的方式: AOP 利用环绕通知,对包含@RequestMapping注 ...
- Spring MVC 使用介绍(五)—— 注解式控制器(一):基本介绍
一.hello world 相对于基于Controller接口的方式,基于注解方式的配置步骤如下: HandlerMapping 与HandlerAdapter 分别配置为RequestMapping ...
- Spring MVC 使用介绍(八)—— 类型转换
一.概述 spring类型转换有两种方式: PropertyEditor:可实现String<--->Object 之间相互转换 Converter:可实现任意类型的相互转换 类型转换的过 ...
- spring mvc简单介绍xml版
spring mvc介绍:其实spring mvc就是基于servlet实现的,只不过他讲请求处理的流程分配的更细致而已. spring mvc核心理念的4个组件: 1.DispatcherServl ...
- Spring MVC 原理介绍(执行流程)
Spring MVC工作流程图 图一 图二 Spring工作流程描述 1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServle ...
- Spring MVC 简单介绍
Spring MVC 是典型的mvc架构,适合web开发. controler 输入输出的控制器,也是对外view提供数据的接口,调用service层. model 数据,由bean组成(相应表),关 ...
随机推荐
- Asp.Net MVC WebAPI的创建与前台Jquery ajax后台HttpClient调用详解
1.什么是WebApi,它有什么用途? Web API是一个比较宽泛的概念.这里我们提到Web API特指ASP.NET MVC Web API.在新出的MVC中,增加了WebAPI,用于提供REST ...
- 深度 | AI芯片终极之战
深度 | AI芯片终极之战 https://mp.weixin.qq.com/s?__biz=MzA4MTQ4NjQzMw==&mid=2652712307&idx=1&sn= ...
- 微耕N3000注入
使用ILSpy或Reflector 反编译N3000并导出解决方案,便于搜索方法代码 使用ILDASM生成中间代码D:\app\WG\AccessControl\IL\N3000.il 操作如下:(可 ...
- java.lang.NoSuchFieldError异常
原因就是主项目的xml文件和库项目中的xml文件 命名一样,导致库项目中的xml文件被主项目覆盖,所以库项目就找不到xml中的相关id,就报异常了. 解决方法:修改主项目中的xml文件命名,不要和 ...
- 性能测试 基于Python结合InfluxDB及Grafana图表实时采集Linux多主机性能数据
基于Python结合InfluxDB及Grafana图表实时采集Linux多主机性能数据 by:授客 QQ:1033553122 实现功能 测试环境 环境搭建 使用前提 使用方法 运行程序 效果展 ...
- WPF:间接支持虚拟化的ListBox
/// <summary> /// 间接实现了虚拟化的ListBox /// 子项必须实现IVisible接口 /// 你可以在IsVisible发生改变时实现一系列自定义动作 /// 比 ...
- WPF开源项目
WPF有很多优秀的开源项目,我以为大家都知道,结果,问了很多人,其实他们不知道.唉,太可惜了! 先介绍两个比较牛逼的界面库 1.MaterialDesignInXamlToolkit Android风 ...
- python3 deque(双向队列)
创建双向队列 import collections d = collections.deque() append(往右边添加一个元素) import collections d = collectio ...
- Arch Linux安装Firefox 火狐中文版
很多人刚安装好系统之后,刚开始内置的浏览器是火狐的英文版,很多时候因为需要账号同步的原因需要国内版本的火狐浏览器,这个时候我们应该怎么操作呢? 其实也非常的简单 首先我们 输入命令 pacman -S ...
- .NET MVC全局异常处理(一)
目录 .NET MVC全局异常处理 IIS配置 静态错误页配置 .NET错误页配置 程序设置 全局异常配置 .NET MVC全局异常处理 一直知道有.NET有相关的配置,但没有实际做过,以为改下设定就 ...