1. 程式人生 > >利用Spring進行統一異常處理的兩種方式

利用Spring進行統一異常處理的兩種方式

package com.jay.platform.exception.handler;

import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;

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

import org.apache.log4j.Logger;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.servlet.ModelAndView;

import com.jay.platform.exception.AjaxException;
import com.jay.platform.utils.DateUtil;

/**
 * @ClassName: WebExceptionHandler
 * @Description: Web層異常處理器,  -- 這裡可以根據不同的異常,寫多個方法去處理, 可以處理跳轉頁面請求,跳到異常指定的錯誤頁,
 *                                                       也可以處理Ajax請求,根據不通過異常,在頁面輸出不同的提示資訊
 *                operateExp          :   處理普通請求
 *                operateExpAjax      :       處理Ajax請求
 * @author Jay He
 * @date 2015年5月27日 下午5:16:37
 * 
 */
@ControllerAdvice
public class WebExceptionHandler {
    
    Logger logger =  Logger.getLogger(WebExceptionHandler.class);
    /*
     * 如果丟擲UnauthorizedException,將被該異常處理器截獲來顯示沒有許可權資訊
     */
    @ExceptionHandler({ UnauthorizedException.class })
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ModelAndView unauthenticatedException(NativeWebRequest request,
	    UnauthorizedException e) {
	ModelAndView mv = new ModelAndView();
	mv.addObject("exception", e);
	mv.setViewName("base/exception/unauthorized");
	return mv;
    }

    /**
     * @Title: operateExp
     * @Description: 全域性異常控制,記錄日誌
     *              任何一個方法發生異常,一定會被這個方法攔截到。然後,輸出日誌。封裝Map並返回給頁面顯示錯誤資訊: 
     *              特別注意:返回給頁面錯誤資訊只在開發時才使用,上線後,要把錯誤頁面去掉,只打印log日誌即可,防止資訊外漏
     * @param: @param ex
     * @param: @param request
     * @return: String
     * @throws:
     */
    @ExceptionHandler(RuntimeException.class)
    public String operateExp(RuntimeException ex, HttpServletRequest request) {
	logger.error(ex.getMessage(), ex);
	logger.info("************* ------ 異常資訊已記錄(" + DateUtil.getNow("yyyy-MM-dd HH:mm:ss")+ ") ------- ***********");
	request.setAttribute("errorTips", ex.getMessage());
	request.setAttribute("ex", ex);
	return "exception/error";
    }
    
    /*
     * 記錄Ajax異常日誌,並將錯誤Ajax錯誤資訊傳遞(回寫)給前臺展示,
     * 前臺的jQuery的Ajax請求error中,可以列印錯誤提示資訊   --  data.responseText   : 這裡即是後臺傳遞的錯誤提示
     * eg:
     * $.ajax({
	            type : 'get',
	            dataType : "json",
	            url : ctx + '/test/test',
	            accept:"application/json",
	            success : function(data) {
	            	console.log(data);
	            },
	            error : function(data, errorThrown) {
	                console.log(data);
	                alert("error" + data.responseText);
	            }
	        });
     */
    @ExceptionHandler(AjaxException.class)
    public void operateExpAjax(AjaxException ex, HttpServletResponse response) throws IOException {
	logger.error(ex.getMessage(), ex);
	logger.info("************* ------ 異常資訊已記錄(" + DateUtil.getNow("yyyy-MM-dd HH:mm:ss")+ ") ------- ***********");
	//將Ajax異常資訊回寫到前臺,用於頁面的提示
	response.getWriter().write("sorry,Ajax請求出錯!!!");
    }
    
    
    @ExceptionHandler(ConnectException.class)
    public void operateExpNetException(ConnectException ex, HttpServletResponse response) throws IOException {
	logger.error(ex.getMessage(), ex);
	logger.info("************* ------ 異常資訊已記錄(" + DateUtil.getNow("yyyy-MM-dd HH:mm:ss")+ ") ------- ***********");
	//將Ajax異常資訊回寫到前臺,用於頁面的提示
	    response.getWriter().write("sorry,網路連接出錯!!!");
    }
}