1. 程式人生 > >springmvc自定義異常

springmvc自定義異常

寫程式碼過程中,經常需要再程式碼裡寫try catch,比較麻煩。可以單獨抽取出來。

先看效果

1普通調整異常頁面

2ajax異常返回

直接上程式碼了

1.再spring-mvc.xml中配置自定義異常類

    	<!-- 異常處理類 -->
	<bean id="exceptionHandler"
		class="com.ncme.common.exception.GlobalExceptionResolver" />
	

2、異常類寫法

package com.ncme.common.exception;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

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

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.ncme.common.dto.AjaxResult;
import com.ncme.common.util.JSONHelper;
/**
 * spring mvc 全域性處理異常捕獲 根據請求區分ajax和普通請求,分別進行響應.
 * 第一、異常資訊輸出到日誌中。
 * 第二、擷取異常詳細資訊的前50個字元,寫入日誌表中t_s_log。
 */
@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
        boolean isajax = isAjax(request,response);
        Throwable deepestException = deepestException(ex);
        return processException(request, response, handler, deepestException, isajax);
	}
	/**
	 * 判斷當前請求是否為非同步請求.
	 */
	private boolean isAjax(HttpServletRequest request, HttpServletResponse response){
		return isNotEmpty(request.getHeader("X-Requested-With"));
	}
	public static boolean isNotEmpty(Object object) {
		if (object != null && !object.equals("") && !object.equals("null")) {
			return (true);
		}
		return (false);
	}
	/**
	 * 獲取最原始的異常出處,即最初丟擲異常的地方
	 */
    private Throwable deepestException(Throwable e){
        Throwable tmp = e;
        int breakPoint = 0;
        while(tmp.getCause()!=null){
            if(tmp.equals(tmp.getCause())){
                break;
            }
            tmp=tmp.getCause();
            breakPoint++;
            if(breakPoint>1000){
                break;
            }
        } 
        return tmp;
    }
	/**
	 * 處理異常.
	 * @param request
	 * @param response
	 * @param handler
	 * @param deepestException
	 * @param isajax
	 * @return
	 */
	private ModelAndView processException(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			Throwable ex, boolean isajax) {
		//步驟一、異常資訊記錄到日誌檔案中.
//		log.error("全域性處理異常捕獲:", ex);
		//步驟二、異常資訊記錄擷取前50字元寫入資料庫中.
//		logDb(ex);
		//步驟三、分普通請求和ajax請求分別處理.
		if(isajax){
			return processAjax(request,response,handler,ex);
		}else{
			return processNotAjax(request,response,handler,ex);
		}
	}
	/**
	 * 異常資訊記錄擷取前50字元寫入資料庫中
	 * @param ex
	 */
/*	private void logDb(Throwable ex) {
		//String exceptionMessage = getThrowableMessage(ex);
		String exceptionMessage = "錯誤異常: "+ex.getClass().getSimpleName()+",錯誤描述:"+ex.getMessage();
		if(oConvertUtils.isNotEmpty(exceptionMessage)){
			if(exceptionMessage.length() > WIRTE_DB_MAX_LENGTH){
				exceptionMessage = exceptionMessage.substring(0,WIRTE_DB_MAX_LENGTH);
			}
		}
		systemService.addLog(exceptionMessage, LOG_OPT,LOG_LEVEL);
	}*/
	/**
	 * ajax異常處理並返回.
	 * @param request
	 * @param response
	 * @param handler
	 * @param deepestException
	 * @return
	 */
	private ModelAndView processAjax(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			Throwable deepestException){
		ModelAndView empty = new ModelAndView();
		response.setContentType("application/json;charset=UTF-8");
//		response.setContentType("text/plain;charset=UTF-8");
		response.setHeader("Cache-Control", "no-store");
		AjaxResult ajaxResult=new AjaxResult();
		ajaxResult.setSuccess(false);
		ajaxResult.setMsg(deepestException.getMessage());
		PrintWriter pw = null;
		try {
			pw=response.getWriter();
			pw.write(JSONHelper.bean2json(ajaxResult));
			pw.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				pw.close();
			} catch (Exception e2) {
			}
		}
		empty.clear();
		return empty;
	}
	/**
	 * 普通頁面異常處理並返回.
	 * @param request
	 * @param response
	 * @param handler
	 * @param deepestException
	 * @return
	 */
	private ModelAndView processNotAjax(HttpServletRequest request,
			HttpServletResponse response, Object handler, Throwable ex) {
		String exceptionMessage = getThrowableMessage(ex);
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("ErrorMsg", ex);
		model.put("stack", exceptionMessage);
		return new ModelAndView("failure", model);
	}
	/**
	 * 返回錯誤資訊字串
	 * 
	 * @param ex
	 *            Exception
	 * @return 錯誤資訊字串
	 */
	public String getThrowableMessage(Throwable ex) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		ex.printStackTrace(pw);
		return sw.toString();
	}
}

3.定義異常跳轉錯誤頁面failure.jsp

<%@	page contentType="text/html;charset=utf-8"%>
<!DOCTYPE HTML>
<html>
	<head>
		<title>Failure</title>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<script type="text/javascript">
			function forback()
			{
				if(window.history.length==0)
				{
					window.close();
				}
				else
				{
					window.history.back();
				}
			}
	</script>
		<style type="text/css">
#Error {
	COLOR: #B22222;
	FONT-SIZE: 14px;
}
</style>
	</head>
	<body leftmargin="0" topmargin="0" class="body1">
		<center>
			<TABLE width="100%" height="600" border="0" cellPadding="0"
				cellSpacing="0">
				<tr>
					<td align="center">
						<table width="70%" border="0" cellpadding="1" cellspacing="0"
							bordercolor="#BDC7D6" bgcolor="#BDC7D6">
							<tr>
								<td>
									<table width="100%" border="0" cellpadding="0" cellspacing="0"
										bordercolor="#BDC7D6" bgcolor="#FFFFFF" class="lankuang1">
										<tr>
											<td height="25" align="left" valign="middle"
												bgcolor="#EFF3F7" class="lanbottom">
												<strong style="color: #5F9EA0">報錯提醒:${ErrorMsg }</strong>
											</td>
										</tr>
										<tr>
											<td height="120" align="center">
												<table width="90%" border="0" cellspacing="0"
													cellpadding="0">
													<tr>
														<td width="73%" align="left" valign="middle">
															<span onclick="showError()" style="cursor:pointer">出錯了,請聯絡管理員!</span>
														</td>
													</tr>
													<tr>
														<td colspan="2" align="center">
															<input type="button" name="forward" value="返回  "
																class="but2" onClick="forback();">
														</td>
													</tr>
												</table>
											</td>
										</tr>
									</table>
								</td>
							</tr>
						</table>
					</td>
				</tr>
			</TABLE>
						</center>
													<div style="display:none" id="errorcode">
														<span id="Error">資訊:${ErrorMsg }</span>
														<br/>
														---------------------------------
														堆疊:
														${stack }
														-----------
													</div>
	
	</body>
	<script type="text/javascript">
		function showError(){
			document.getElementById("errorcode").style.display="block";
		}
	</script>
</html>