異常分類,異常處理,全局異常攔截

什麼是異常:

如果某個方法不能按照正常的途徑完成執行,就可以通過另一種路徑退出方法(異常攔截)。在這種情況下會拋出一個封裝了錯誤信息的對象(異常對象)。
異常就是編譯和運行時出現的一些錯誤,Java語言把一些常見的問題封裝成了對象。比如ArrayIndexOutofBoundsException,封裝了一些錯誤錯的原因,以及其他的一些異常信息

異常的分類:

異常的根類: Throwable

異常的子類: Error (嚴重錯誤,無法解決)

編譯時異常:Execption (可以通過代碼控制解決)

Error:

Error是throwable的子類,他是程序出現嚴重的問題,這種問題程序解決不了。
如:因爲內存溢出或沒有可用的內存提供給垃圾回收器時,java虛擬機無法分配一個對象,這時拋出該異常。

Execption:

Exception 又有兩個細分 ,一個是運行時異常 RuntimeException , 一 個是檢查異常 CheckedException。

RuntimeException 是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。 如果出現 RuntimeException,那麼一定是程序員代碼書寫導致的錯誤.

CheckedException:一般是外部錯誤,這種異常都發生在編譯階段,Java 編譯器會強制程序去捕獲此類異常,即會出現要求你把這段可能出現異常的程序進行 try catch

異常處理:

第一種方式try/catch攔截
try{
    xxxxxxxxxx
    xxxxxx
//檢測到代碼異常,直接進入到catch
}catch(Exception e){
	syso(異常原因:e.getMessage())
	//相關處理
}
第二種方式多異常處理
多異常處理針對複雜代碼,在不確定可能拋出異常具體類型的情況下,通過多個catch攔截
注意最大的異常要放在最下面.
try{
    xxxxxxxxxx
    xxxxxx
//檢測到代碼異常,直接進入到catch
}catch(Exception e){
	syso(異常原因:e.getMessage())
	//相關處理
}catch(Exception e2){
	syso(異常原因:e2.getMessage())
	//相關處理
}catch (Exception e3){
	syso(異常原因:e3.getMessage())
	//相關處理
}
finaly使用
注意:如果finaly同時存在return,先執行finaly在執行return返回
try{
    xxxxxxxxxx
    xxxxxx
//檢測到代碼異常,直接進入到catch
}catch(Exception e){
	syso(異常原因:e.getMessage())
	//相關處理
}catch(Exception e2){
	syso(異常原因:e2.getMessage())
	//相關處理
}catch (Exception e3){
	syso(異常原因:e3.getMessage())
	//相關處理
} finaly{
	//相關處理
}

拋出異常有三種形式,

throw 和 throws,還有一種系統自動拋異常。

  • throws :拋出異常,在方法聲明上,後面跟異常類 示例: throws Exception
  • thorw: 拋出異常在方法體中,後面跟異常對象, 示例: throw new
    SQLIntegrityConstraintViolationException(“單位信息導入模板數據錯誤,在第” + index + “條記錄的企業唯一數據重複!”);
  • 如果異常不進行攔截:
    如果代碼中異常不進行try/catch攔截,沒有手動拋出,系統會自動把代碼拋給方法調用者,這是不允許的,所以合理的異常攔截和處理是非常有必要的.

自定義全局異常攔截

異常示例
	try {
				companyService.insertSelective(com); //新增數據
			} catch (Exception e) { //攔截異常
				String errMsg = e.getMessage();
				//判斷異常類型爲違反唯一索引異常
				if (StringUtils.isNotBlank(errMsg) && "java.sql.SQLIntegrityConstraintViolationException"
						.equals(e.getCause().getClass().getName())) {
					// 通過throw拋出數據庫唯一索引異常,並指定異常內容
					throw new SQLIntegrityConstraintViolationException("單位信息導入模板數據錯誤,在第" + index + "條記錄的企業唯一數據重複!");
				}
				// 拋出大異常Exception
				throw e;
			}
全局異常攔截示例
### @ExceptionHandler 異常處理器:攔截指定異常,在{}花括號內可以同時存在多個異常,中間用逗號分隔
/**
 * shiro 全局異常處理 Controller繼承BaseController公共異常類,在拋出異常時會攔截異常處理器
 * 
 * @ExceptionHandler 全局異常處理器
 *                   登錄認證異常:UnauthenticatedException,AuthenticationException
 *                   權限認證異常:UnauthorizedException,AuthorizationException
 * @author 張江豐
 *
 */
@Component
public class BaseController {
	/**
	 * 登錄認證異常
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	// @ExceptionHandler({ UnauthenticatedException.class,
	// AuthenticationException.class })
	@ExceptionHandler({ UnauthenticatedException.class })
	public String authenticationException(HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> map = new HashMap<>();
		map.put("status", "-1000");
		map.put("message", "未登錄");
		writeJson(map, response);
		return null;
	}

	/**
	 * 攔截數據庫唯一索引異常
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@ExceptionHandler({ SQLIntegrityConstraintViolationException.class })
	public void SQLIntegrityConstraintViolationException(HttpServletRequest request, HttpServletResponse response,
			SQLIntegrityConstraintViolationException sql) {
		String path = request.getServletPath();
		System.out.println("====================請求路徑:" + path + ";攔截數據庫唯一索引錯誤提示信息:" + sql.getMessage());
		Map<String, Object> map = new HashMap<>();
		if (path.contains("readExcel")) {
			// 導入信息報錯
			map.put("code", "-1001");
			//手動throw拋出數據庫唯一索引異常,和異常內容
			map.put("msg", sql.getMessage());
		} else {
			map.put("code", "-1001");
			map.put("msg", "新增信息失敗,存在唯一數據重複!");
		}
		writeJson(map, response);
	}

	/**
	 * 攔截運行時異常
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@ExceptionHandler({ RuntimeException.class })
	public void RuntimeException(HttpServletRequest request, HttpServletResponse response, RuntimeException re) {
		Map<String, Object> map = new HashMap<>();
		String path = request.getServletPath();
		System.out.println("====================全局運行時異常,請求路徑:" + path + ";錯誤提示信息:" + re.getMessage());
		// 其它運行時異常
		map.put("code", "-1001");
		map.put("msg", "信息錯誤,請聯繫管理員!");
		writeJson(map, response);
	}

	/**
	 * 權限異常
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@ExceptionHandler({ UnauthorizedException.class, AuthorizationException.class })
	public void authorizationException(HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> map = new HashMap<>();
		map.put("code", "-1001");
		map.put("msg", "無操作權限");
		writeJson(map, response);
	}

	private void writeJson(Map<String, Object> map, HttpServletResponse response) {
		// 字符打印流
		PrintWriter out = null;
		try {
			response.setCharacterEncoding("UTF-8");
			response.setContentType("application/json; charset=utf-8");
			out = response.getWriter();
			JSONObject mapJson = JSONObject.fromObject(map);
			String string = mapJson.toString();
			out.write(string);
		} catch (IOException e) {
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章