通常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请求异常)的更多相关文章

  1. 2017.3.31 spring mvc教程(六)转发、重定向、ajax请求

    学习的博客:http://elf8848.iteye.com/blog/875830/ 我项目中所用的版本:4.2.0.博客的时间比较早,11年的,学习的是Spring3 MVC.不知道版本上有没有变 ...

  2. Vue框架axios请求(类似于ajax请求)

    Vue框架axios get请求(类似于ajax请求) 首先介绍下,这个axios请求最明显的地方,通过这个请求进行提交的时候页面不会刷新 <!DOCTYPE html> <html ...

  3. 利用x-requested-with判断请求是否是Ajax请求

    在服务器端判断request来自Ajax请求(异步)还是传统请求(同步):         两种请求在请求的Header不同,Ajax 异步请求比传统的同步请求多了一个头参数 1.传统同步请求参数 a ...

  4. 判断一个请求是否为Ajax请求

    这几天在写一个网站的登录判断拦截器,需要对请求进行拦截,在拦截器中我需要判断HttpServletRequest是否为Ajax异步请求.我们可以通过X-Requested-With="XML ...

  5. java端拦截器判断客户的的请求是否是ajax请求

    java端拦截器判断客户的的请求是否是ajax请求 发表于 2014-08-22 23:38:08 普通请求与ajax请求的报文头不一样,通过如下 String requestType = reque ...

  6. Spring MVC自定义统一异常处理类,并且在控制台中输出错误日志

    在使用SimpleMappingExceptionResolver实现统一异常处理后(参考Spring MVC的异常统一处理方法), 发现出现异常时,log4j无法在控制台输出错误日志.因此需要自定义 ...

  7. spring MVC 管理HttpClient---实现在java中直接向Controller发送请求

    在spring MVC中,大多数时候是由客户端的页面通过ajax等方式向controller发送请求,但有时候需要在java代码中直接向controller发送请求,这时可以使用HttpCilent实 ...

  8. Spring MVC 3 表单中文提交post请求和get请求乱码问题的解决方法

    在spring mvc 3.0 框架中,通过JSP页面.HTML页面以POST方式提交表单时,表单的参数传递到对应的servlet后会出现中文显示乱码的问题.解决办法可采用spring自带的过滤技术, ...

  9. spring mvc 第二天【注解实现springmvc Handler处理ajax简单请求 的配置】

    这里使用的是在前台发起ajax请求Handler,后台伪造数据响应给前台, 配置对应ajax请求的Handler信息如下 @Controller public class MyController { ...

  10. spring mvc 坑之PUT,DELETE方法接收不到请求参数

    https://www.cnblogs.com/roobtyan/p/9576685.html 原因: Tomcat处理参数的问题: 1.将请求体中的数据,封装成一个map    2.request. ...

随机推荐

  1. IReport制作报表——日期时间显示格式

    转自:https://blog.csdn.net/linglinglu/article/details/9022679?utm_source=blogxgwz2 IReport工具在制作报表的时候,会 ...

  2. 基于thinkphp5的Excel上传

    涉及知识点: thinkphp5.0: excel上传: mysql建立新表(基本的create语句): mysql ignore(避免重复插入): 主要功能: 通过在视图中上传excel文件,在my ...

  3. luogu P3600 随机数生成器【dp】

    把期望改成方案数最后除一下,设h[i]为最大值恰好是i的方案数,那么要求的就是Σh[i]*i 首先包含其他区间的区间是没有意义的,用单调栈去掉 然后恰好不好求,就改成h[i]表示最大值最大是i的方案数 ...

  4. IT兄弟连 JavaWeb教程 JSP内置对象经典面试题

    1.请说明cookie.request.session.application的作用域和声明周期? 并说明它们适用与什么场景? request的生命周期是一次请求.可以用于JSP表单提交数据. ses ...

  5. webpack结合vue使用(五)

    webpack结合vue使用步骤如下: 安装 vue 的包 : cnpm i vue -S 由于在 webpack 中,锐减使用 .vue 这个组件模板文件定义组件,所以需要安装能解析这种文件的第三方 ...

  6. B - Halloween Costumes

    #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> ...

  7. D. Pair Of Lines( Educational Codeforces Round 41 (Rated for Div. 2))

    #include <vector> #include <iostream> #include <algorithm> using namespace std; ty ...

  8. linux常用命令(ubuntu)

    编辑: vi [path] vim [path] :q 退出 :wq 保存退出 查看进程 ps ps -aux | grep mem 查看全部含 “mem”的进程 ps –aux  查看全部 在系统启 ...

  9. 归档-对模型数组对象(存储到本地的plist文件)也数组里存放的是模型

    一.模型文件 (1)JLMainViewsModel.h文件 必须遵循 NSCoding协议 @interface JLMainViewsModel : NSObject<NSCopying,N ...

  10. python基本的数据类型

    一.python的基本数据类型 int => 整数,主要用来进行数学运算 str ==> 字符串 可以用来保存少量数据并进行相应操作 bool ==> 判断真假,True,False ...