[Spring-MVC] 3 异常统一处理

绝大多数情况下,其实程序对于exception并没有自我解决的能力,一般情况对于exception都进行2个操作:1、日志记录,2、给予友好的界面提示,并返回错误信息

针对这一特点,在一般情况下,在dao、service、action层,均不作异常捕获,一律抛出。
在action层抛出异常之后,使用springmvc框架中的HandlerExceptionResolver对异常进行全局性处理


定义一个类,实现org.springframework.web.servlet.HandlerExceptionResolver接口

在这个类中对AJAX请求和非AJAX请求分别进行处理


package com.fhzz.core.handler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import com.fhzz.core.utils.HTTPUtils;

/**
 * @author YangYi
 * 
 *         统一的全局异常处理,当controller层抛出异常时,由此类统一处理
 */
@Component
public class CustomHandlerExceptionResolver implements HandlerExceptionResolver {
	Log logger = LogFactory.getLog(CustomHandlerExceptionResolver.class);

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object object,
			Exception exception) {
		logger.error(exception.getMessage(), exception);// 异常日志记录
		// 判断是否AJAX请求
		if (!HTTPUtils.isAjaxRequest(request)) {// 如果不是AJAX请求,VM格式返回
			ModelAndView modelAndView = new ModelAndView("error/errorInfoPage"); // 统一跳转到errorPage页面
			modelAndView.addObject("success", false);
			modelAndView.addObject("errorMsg", exception.getMessage());
			return modelAndView;
		} else {// 如果是AJAX请求,JSON格式返回
			ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
			modelAndView.addObject("success", false);
			modelAndView.addObject("errorMsg", exception.getMessage());
			return modelAndView;
		}
	}
}

1、如果界面跳转的请求,则统一跳转到errorPage界面,并将错误信息显示于界面上

  在界面上使用$errorMsg即可获得错误信息


2、如果是AJAX请求,则返回JSON格式的错误信息
扩展jquery的ajax方法(由于$.post实际上底层 也是调用的$.ajax,所以扩展了$.ajax方法之后,不论$.ajax还是$.post都会执行这段代码逻辑)
$(function() {
	// 首先备份下jquery的ajax方法
	var _ajax = $.ajax;
	// 重写jquery的ajax方法
	$.ajax = function(opt) {
		// 备份opt中error和success方法
		var fn = {
			error : function(XMLHttpRequest, textStatus, errorThrown) {
			},
			success : function(data, textStatus) {
			}
		}
		if (opt.error) {
			fn.error = opt.error;
		}
		if (opt.success) {
			fn.success = opt.success;
		}
		// 扩展增强处理
		var _opt = $.extend(opt, {
			error : function(XMLHttpRequest, textStatus, errorThrown) {
				switch (XMLHttpRequest.status) {
				case 400:
					// 未授权异常
					alert("请求无效");
					break;
				case 403:
					// 未授权异常
					alert("您没有访问权限");
					break;
				case 404:
					alert("您访问的资源不存在");
					break;
				case 500:
					alert("内部服务器错误");
					break;
				}
				// 打印responseText,方便排查问题
				console.log(XMLHttpRequest.responseText);
				// 错误方法增强处理
				fn.error(XMLHttpRequest, textStatus, errorThrown);
			},
			success : function(data, textStatus) {
				if (data.sessionInvalid) {
					// 跳转到登录页面,这里要加上top.为了防止在iframe界面中弹出了登录界面
					top.location.href = 'toLogin.do?message=' + data.message;
					return;
				}
				if (!textStatus) {
					showMsg(data.errorMsg, "操作失败,错误信息", 0, 200, 400);
				} else if (typeof (data.success) != 'undefined'
						&& !data.success) {
					showMsg(data.errorMsg, "操作失败,错误信息", 0, 200, 400);
				} else {
					fn.success(data, textStatus);// 成功回调方法增强处理
				}
			},
			beforeSend : function(XHR) {
				// 提交前回调方法,全局统一的等待提示框
				// 例如$('body').append("<div id='ajaxInfo'
				// style=''>正在加载,请稍后...</div>");
			},
			complete : function(XHR, TS) {
				// 请求完成后回调函数 (请求成功或失败之后均调用)。
				// 取消全局统一的等待提示框,例如//$("#ajaxInfo").remove();
			}
		});
		return _ajax(_opt);
	};
});


此处一并加入了403,404错误的返回信息,这类错误会直接进入error方法内
返回403错误的方法具体参考Spring-securtiy相关内容中的CustomAccessDeniedHandler
所以使用

而本文中的CustomHandlerExceptionResolver 返回的信息会进入success方法

有其中的success 设置为了false,errorMsg为exception.getMessage() ,这里可以根据实际情况进行更如何用户需要的展示

if (!textStatus) {
	showMsg(data.errorMsg, "操作失败,错误信息", 0, 200, 400);
} else if (typeof (data.success) != 'undefined'	&& !data.success) {
	showMsg(data.errorMsg, "操作失败,错误信息", 0, 200, 400);
} else {
	fn.success(data, textStatus);// 成功回调方法增强处理
}

可以在界面进行统一处理
那么action就可以完全专注于正常逻辑的处理,而异常直接交由了框架负责




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值