通常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. pdf2swf 转换时报This file is too complex to render- SWF only supports 65536 shapes at once

    ERROR   ID Table overflow ERROR   This file is too complex to render- SWF only supports 65536 shapes ...

  2. 2.12 Hivet中order by,sort by、distribute by和cluster by

    https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy 一.order by 对全局数据的排序,仅仅只有一个red ...

  3. 3.16 使用Zookeeper对HDFS HA配置自动故障转移及测试

    一.说明 从上一节可看出,虽然搭建好了HA架构,但是只能手动进行active与standby的切换: 接下来看一下用zookeeper进行自动故障转移: # 在启动HA之后,两个NameNode都是s ...

  4. 3-2if条件结构

    不同条件做不同的操作.例如满100就减去20 条件结构 package com.imooc.operator; public class ConditionDemo1 { public static ...

  5. CCF 201512-4 送货 (并查集+DFS,欧拉路)

    问题描述 为了增加公司收入,F公司新开设了物流业务.由于F公司在业界的良好口碑,物流业务一开通即受到了消费者的欢迎,物流业务马上遍及了城市的每条街道.然而,F公司现在只安排了小明一个人负责所有街道的服 ...

  6. LeetCode: 557Reverse Words in a String III(easy)

    题目: Given a string, you need to reverse the order of characters in each word within a sentence while ...

  7. c++指针参数是如何传递内存的

    参数策略 如果函数的参数是一个指针,不要指望用该指针去动态申请内存.如下: void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(c ...

  8. ajaxForm上传文件到本地服务器(封装)

    不啰嗦,直接看代码 1.html: <div class="con-item fix"> <span class="f">文章封面< ...

  9. P5135 painting(组合数)

    传送门 如果\(op==1\),那么每一个方案都可以看做从\(n\)个数里选出\(m\)个数,然后\(sort\)一下依次放到每列,方案数就是\({n\choose m}\).因为\(n\)很大,但是 ...

  10. IT兄弟连 JavaWeb教程 Servlet会话跟踪 创建Cookie

    Tomcat作为Web服务器,对Cookie提供了良好的支持.那么,运行在Tomcat的Servlet该如何访问Cookie呢?幸运的是,Servlet无需直接和HTTP请求或响应中的原始Cookie ...