Spring MVC异常统一处理(包括普通请求异常以及ajax请求异常)
通常SpringMVC对异常的配置都是返回某个jsp视图给用户,但是通过ajax方式发起请求,即使发生异常,前台也无法获得任何异常提示信息。因此需要对异常进行统一的处理,对于普通请求以及ajax请求的异常都有效。
1.Spring MVC的异常处理机制
Spring MVC 通过HandlerExceptionResolver处理程序的异常,包括处理器映射,数据绑定以及处理器执行时发生的异常。HandlerExceptionResolver仅有一个接口方法:
ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);
当发生异常时,Spring MVC将调用resolveException()方法,并转到ModelAndView对应的视图,作为一个异常报告页面反馈给用户。
HandlerExceptionResolver拥有4个实现类,分别是
DefaultHandlerExceptionResolver,
AnnotationMethodExceptionResolver,
ResponseStatusExceptionResolver,
SimpleMappingExceptionResolver.
(1)DefaultHandlerExceptionResolver
Spring MVC默认装配了DefaultHandlerExceptionResolver,它会将Spring MVC框架的异常转换为相应的响应状态码。响应状态码如下:
500:Web服务内部错误
406:无和请求accept匹配的MIME类型
415:不支持的MIME类型
400:坏的请求
405:不支持的请求方法
404:找不到匹配的资源。
可以在web.xml中通过如下配置为响应状态码配置一个对应的页面:
1: <error>
2: <error-code>404</error-code>
3: <location>/404.htm</location>
4: <error-page>
(2)AnnotationMethodHandlerExceptionResolver
Spring MVC已经默认注册了AnnotationMethodHandlerExceptionResolver,它允许通过@ExceptionHandler的注解支持处理特定异常的方法。
1: @Controller
2: public class UserController{
3:
4: @RequestMapping("/throwException")
5: public String throwException(){
6: if (2 > 1) {
7: throw new RuntimeException("ddd")
8: }
9: return "/success";
10: }
11:
12: @ExceptionHandler(RuntimeException.class)
13: public String handlerException(RuntimeException ex,HttpServletRequest request){
14: return "forward:/error.jsp";
15: }
16: }
当调用throwException方法时,会抛出RuntimeException,它会被出于同一个处理器类中的handlerException()方法捕获。@ExceptionHandler可以指定多个异常,但是标注@ExceptionHandler的异常处理方法只能对同一个处理器类中的其他方法进行异常响应处理。
(3)ResponseStatusHandlerExceptionResolver
ResponseStatusHandlerExceptionResolver和AnnotationMethodHandlerExceptionResolver类似,可以通过@ResponseStatus注解标注一个方法,用于处理特定类型的响应状态码。
(4)SimpleMappingHandlerExceptionResolver
SimpleMappingHandlerExceptionResolver将异常类名映射为视图名,即发生异常时使用对应的视图报告异常。
1: <bean id="exceptionResolver"
2: class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
3: <property name="exceptionMappings">
4: <props>
5: <prop key="com.wbl.modal.exception.NoPermissionException">/error</prop>
6: <prop key="com.wbl.modal.exception.NotLoginException">/login</prop>
7: </props>
8: </property>
9: <property name="exceptionAttribute" value="ex"></property>
10: </bean>
我们指定当发生NotLoginException异常,使用login视图进行显示,即用户未登陆时,让用户到登陆页面进行登陆。
2.Spring MVC 的异常统一处理
为了能够对异常进行统一的处理,包括普通请求发生异常以及ajax请求发生异常时,我们可以覆写SimpleMappingHandlerExceptionResolver中的doResolveException()方法,判断是普通请求还是ajax请求。
1: package com.wbl.modal.exception;
2:
3: import org.springframework.web.servlet.ModelAndView;
4: import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
5:
6: import javax.servlet.http.HttpServletRequest;
7: import javax.servlet.http.HttpServletResponse;
8: import java.io.IOException;
9: import java.io.PrintWriter;
10:
11: /**
12: * Created by Simple_love on 2015/9/10.
13: */
14: public class GlobalExceptionResolver extends SimpleMappingExceptionResolver {
15:
16: @Override
17: protected ModelAndView doResolveException(HttpServletRequest request,
18: HttpServletResponse response, Object handler, Exception ex){
19: String viewName = determineViewName(ex,request);
20: response.setCharacterEncoding("UTF-8");
21: if (viewName != null) {// JSP格式返回
22: if (!(request.getHeader("accept").contains("application/json") || (request.getHeader("X-Requested-With")!= null && request
23: .getHeader("X-Requested-With").contains("XMLHttpRequest") ))) {
24: // 如果不是异步请求
25: // Apply HTTP status code for error views, if specified.
26: // Only apply it if we're processing a top-level request.
27: Integer statusCode = determineStatusCode(request, viewName);
28: if (statusCode != null) {
29: applyStatusCodeIfPossible(request, response, statusCode);
30: }
31: System.out.println("JSP格式返回" + viewName);
32: return getModelAndView(viewName, ex, request);
33: } else {// JSON格式返回
34: try {
35: PrintWriter writer = response.getWriter();
36: writer.write(ex.getMessage());
37: writer.flush();
38: } catch (IOException e) {
39: e.printStackTrace();
40: }
41: System.out.println("JSON格式返回" + viewName);
42: return null;
43: }
44: } else {
45: return null;
46: }
47: }
48: }
如果是普通请求则返回对应的视图,如果是ajax请求,则返回抛出的异常信息。
Spring MVC异常统一处理(包括普通请求异常以及ajax请求异常)的更多相关文章
- 2017.3.31 spring mvc教程(六)转发、重定向、ajax请求
学习的博客:http://elf8848.iteye.com/blog/875830/ 我项目中所用的版本:4.2.0.博客的时间比较早,11年的,学习的是Spring3 MVC.不知道版本上有没有变 ...
- Vue框架axios请求(类似于ajax请求)
Vue框架axios get请求(类似于ajax请求) 首先介绍下,这个axios请求最明显的地方,通过这个请求进行提交的时候页面不会刷新 <!DOCTYPE html> <html ...
- 利用x-requested-with判断请求是否是Ajax请求
在服务器端判断request来自Ajax请求(异步)还是传统请求(同步): 两种请求在请求的Header不同,Ajax 异步请求比传统的同步请求多了一个头参数 1.传统同步请求参数 a ...
- 判断一个请求是否为Ajax请求
这几天在写一个网站的登录判断拦截器,需要对请求进行拦截,在拦截器中我需要判断HttpServletRequest是否为Ajax异步请求.我们可以通过X-Requested-With="XML ...
- java端拦截器判断客户的的请求是否是ajax请求
java端拦截器判断客户的的请求是否是ajax请求 发表于 2014-08-22 23:38:08 普通请求与ajax请求的报文头不一样,通过如下 String requestType = reque ...
- Spring MVC自定义统一异常处理类,并且在控制台中输出错误日志
在使用SimpleMappingExceptionResolver实现统一异常处理后(参考Spring MVC的异常统一处理方法), 发现出现异常时,log4j无法在控制台输出错误日志.因此需要自定义 ...
- spring MVC 管理HttpClient---实现在java中直接向Controller发送请求
在spring MVC中,大多数时候是由客户端的页面通过ajax等方式向controller发送请求,但有时候需要在java代码中直接向controller发送请求,这时可以使用HttpCilent实 ...
- Spring MVC 3 表单中文提交post请求和get请求乱码问题的解决方法
在spring mvc 3.0 框架中,通过JSP页面.HTML页面以POST方式提交表单时,表单的参数传递到对应的servlet后会出现中文显示乱码的问题.解决办法可采用spring自带的过滤技术, ...
- spring mvc 第二天【注解实现springmvc Handler处理ajax简单请求 的配置】
这里使用的是在前台发起ajax请求Handler,后台伪造数据响应给前台, 配置对应ajax请求的Handler信息如下 @Controller public class MyController { ...
- spring mvc 坑之PUT,DELETE方法接收不到请求参数
https://www.cnblogs.com/roobtyan/p/9576685.html 原因: Tomcat处理参数的问题: 1.将请求体中的数据,封装成一个map 2.request. ...
随机推荐
- json : json数据解析(一)
在项目中经常用到json格式的数据转换与解析,先前写过一些小例子,现在整理下,以备后用和帮助后来者. 言归正传: 使用到的jar包 :json-lib-2.4-jdk15.jar,当然你也可以用自己版 ...
- android实例3:拖动条
个人网站http://www.ravedonut.com/ 拖动条改变图片的透明度 xml <LinearLayout xmlns:android="http://schemas.an ...
- 爬虫库之BeautifulSoup学习(一)
Beautiful Soup的简介 简单来说,Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据. 官方解释如下: Beautiful Soup提供一些简单的.pytho ...
- PHP实用小程序(一)
<? //设置路径(默认当前php文件所在路径) $basedir = "d:/inetpub/wwwroot"; $textrows = "20"; $ ...
- roguelike地牢生成算法
文章原地址 上一个地图生成算法,这一次是一个地牢的生成算法,是一个国外的人写的算法,用dart语言写,我把它改成了unity-c#. 原作者博客地址:Rooms and Mazes: A Proced ...
- Python3.6 的字符串内建函数
1.capitalize(self) 将字符串的第一个字符转换为大写 2.casefold(self) 返回将字符串中所有大写字符转换为小写后生成的字符串 3.center(self, width, ...
- ORA-22992:没法使用从远程表选择的LOB定位器
OLB 问题 ORA-22992:没法使用从远程表选择的LOB定位器 Create global temporary table temp on commit preserve rows as sel ...
- C# 程序软件启动默认管理员权限。
在vs的Properties目录中找到 app.manifest,将其中level="asInvoker" 改成 level="requireAdministrator& ...
- JSBridge框架解决通信问题实现移动端跨平台开发
一.跨平台开发是趋势 目前主流的移动端平台主要是Android和iOS,为了尽可能复用代码和节省开发成本,各大巨头都开发了自己的跨平台框架,比如Facebook的React-Native.阿里的Wee ...
- Lightoj1081【500棵线段树维护】
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N=5e2+10; const ...