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请求,则返回抛出的异常信息。

时间: 2024-12-16 12:25:57

Spring MVC异常统一处理(包括普通请求异常以及ajax请求异常)的相关文章

Spring MVC +MyBatis +MySQL 简单的登录查询 Demo 解决了mybatis异常

忙活了大半天,饭也没顾得上吃,哎许久不动手,一动手就出事,下面请看今天的重头戏,额吃个饭回来再发了! 1.整体结构 2.准备工作 数据库: --Mysql 5.6 创建数据库 wolf CREATE DATABASE wolf; 创建用户表 user create table user( id int  AUTO_INCREMENT  primary key, name varchar(25) not null, pwd varchar(20) not null, create_time dat

java判断请求是否为ajax请求

/** * isAjaxRequest:判断请求是否为Ajax请求. <br/> * @param request 请求对象 * @return boolean * @since JDK 1.6 */ public boolean isAjaxRequest(HttpServletRequest request){ String header = request.getHeader("X-Requested-With"); boolean isAjax = "XM

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

1 java端拦截器判断客户的的请求是否是ajax请求 2 3 4 发表于 2014-08-22 23:38:08 5 普通请求与ajax请求的报文头不一样,通过如下 6 7 String requestType = request.getHeader("X-Requested-With"); 8 9 如果requestType能拿到值,并且值为XMLHttpRequest,表示客户端的请求为异步请求,那自然是ajax请求了,反之如果为null,则是普通的请求 10 11 http:/

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

Vue框架axios get请求(类似于ajax请求) 首先介绍下,这个axios请求最明显的地方,通过这个请求进行提交的时候页面不会刷新 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="vue.js"></scr

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

在spring MVC中,大多数时候是由客户端的页面通过ajax等方式向controller发送请求,但有时候需要在java代码中直接向controller发送请求,这时可以使用HttpCilent实现. 首先用到的包是httpclient-4.3.5.jar和httpcore-4.3.2.jar 先看下面代码: package module.system.common; import java.io.IOException; import java.util.ArrayList; import

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

在使用SimpleMappingExceptionResolver实现统一异常处理后(参考Spring MVC的异常统一处理方法), 发现出现异常时,log4j无法在控制台输出错误日志.因此需要自定义一个继承至SimpleMappingExceptionResolver的 RrtongMappingExceptionResolver类,在RrtongMappingExceptionResolver中通过 log.error(ex.getMessage())的方式输出日志到控制台上.以下是具体的配

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

这里使用的是在前台发起ajax请求Handler,后台伪造数据响应给前台, 配置对应ajax请求的Handler信息如下 1 @Controller 2 public class MyController { 3 //处理器方法 4 @RequestMapping(value="/first.do",produces="text/html;charset=utf-8") 5 public void doFirst(HttpServletResponse respon

jQuery+ASP.NET MVC基于CORS实现带cookie的跨域ajax请求

这是今天遇到的一个实际问题,在这篇随笔中记录一下解决方法. ASP.NET Web API提供了CORS支持,但ASP.NET MVC默认不支持,需要自己动手实现.可以写一个用于实现CORS的ActionFilterAttribute,我们就是这么实现的: public class AllowCorsAttribute : ActionFilterAttribute { private string[] _domains; public AllowCorsAttribute(string dom

关于 x-requested-with 请求头 区分ajax请求还是普通请求

今天做Spring MVC异常统一处理这块,在处理的时候需要区分发送过来的请求是传统请求还是ajax请求,网上有现成的代码,我是参考http://www.2cto.com/kf/201412/364393.html 里面的做法.其中的 if (!( request.getHeader("accept").indexOf("application/json") > -1 || ( request                     .getHeader(&q

java如何区分是form表单请求,还是ajax请求

requestType = request.getHeader("X-Requested-With");                 if(requestType==null){//form表单请求                                  }else{//ajax请求                                    }