本文主要介紹springmvc中異常處理的思路,並展示如何自定義異常處理類以及全局異常處理器的配置
系統中異常包括兩類:
預期異常 運行時異常RuntimeException前者通過捕獲異常從而獲取異常信息,後者主要通過規范代碼開發、測試通過手段減少運行時異常的發生。
系統的dao、service、controller出現都通過throws Exception向上拋出,最後由springmvc前端控制器交由異常處理器進行異常處理,如下圖:
springmvc提供全局異常處理器(一個系統只有一個異常處理器)進行統一異常處理。
對不同的異常類型定義異常類,繼承Exception。
package com.iot.learnssm.firstssm.exception;
/**
* Created by brian on 2016/3/7.
*
* 系統 自定義異常類,針對預期的異常,需要在程序中拋出此類的異常
*/
public class CustomException extends Exception{
//異常信息
public String message;
public CustomException(String message){
super(message);
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
思路:
系統遇到異常,在程序中手動拋出,dao拋給service、service給controller、controller拋給前端控制器,前端控制器調用全局異常處理器。
全局異常處理器處理思路:
解析出異常類型
如果該異常類型是系統自定義的異常,直接取出異常信息,在錯誤頁面展示 如果該異常類型不是系統自定義的異常,構造一個自定義的異常類型(信息為“未知錯誤”)springmvc提供一個HandlerExceptionResolver
接口
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
//handler就是處理器適配器要執行Handler對象(只有method)
//解析出異常類型
//如果該 異常類型是系統 自定義的異常,直接取出異常信息,在錯誤頁面展示
//String message = null;
//if(ex instanceof CustomException){
//message = ((CustomException)ex).getMessage();
//}else{
////如果該 異常類型不是系統 自定義的異常,構造一個自定義的異常類型(信息為“未知錯誤”)
//message="未知錯誤";
//}
//上邊代碼變為
CustomException customException;
if(ex instanceof CustomException){
customException = (CustomException)ex;
}else{
customException = new CustomException("未知錯誤");
}
//錯誤信息
String message = customException.getMessage();
ModelAndView modelAndView = new ModelAndView();
//將錯誤信息傳到頁面
modelAndView.addObject("message", message);
//指向錯誤頁面
modelAndView.setViewName("error");
return modelAndView;
}
}
<%--
Created by IntelliJ IDEA.
User: Brian
Date: 2016/3/4
Time: 10:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
${message}
全局異常處理器只有一個,配置多個也沒用。
在controller、service、dao中任意一處需要手動拋出異常。如果是程序中手動拋出的異常,在錯誤頁面中顯示自定義的異常信息,如果不是手動拋出異常說明是一個運行時異常,在錯誤頁面只顯示“未知錯誤”。
在商品修改的controller方法中拋出異常 .
public String editItems(Model model,@RequestParam(value="id",required=true) Integer items_id)throws Exception {
//調用service根據商品id查詢商品信息
ItemsCustom itemsCustom = itemsService.findItemsById(items_id);
//判斷商品是否為空,根據id沒有查詢到商品,拋出異常,提示用戶商品信息不存在
if(itemsCustom == null){
throw new CustomException("修改的商品信息不存在!");
}
//通過形參中的model將model數據傳到頁面
//相當於modelAndView.addObject方法
model.addAttribute("items", itemsCustom);
return "items/editItems";
}
在service接口中拋出異常:
public ItemsCustom findItemsById(Integer id) throws Exception {
Items items = itemsMapper.selectByPrimaryKey(id);
if(items==null){
throw new CustomException("修改的商品信息不存在!");
}
//中間對商品信息進行業務處理
//....
//返回ItemsCustom
ItemsCustom itemsCustom = null;
//將items的屬性值拷貝到itemsCustom
if(items!=null){
itemsCustom = new ItemsCustom();
BeanUtils.copyProperties(items, itemsCustom);
}
return itemsCustom;
}
如果與業務功能相關的異常,建議在service中拋出異常。 與業務功能沒有關系的異常,建議在controller中拋出。
上邊的功能,建議在service中拋出異常。