package yycg.base.process.result; /** * 自定義系統異常類 */ public class ExceptionResultInfo extends Exception { // 系通通一使用的結果類,包括了 提示信息類型和信息內容 private ResultInfo resultInfo; public ExceptionResultInfo(ResultInfo resultInfo) { super(resultInfo.getMessage()); this.resultInfo = resultInfo; } public ResultInfo getResultInfo() { return resultInfo; } public void setResultInfo(ResultInfo resultInfo) { this.resultInfo = resultInfo; } }
package yycg.base.process.result; import java.util.HashMap; import java.util.List; import java.util.Map; import yycg.util.ResourcesUtil; /** * 系統提示信息封裝類 * @author mrt * */ public class ResultInfo { public static final int TYPE_RESULT_FAIL = 0;//失敗 public static final int TYPE_RESULT_SUCCESS = 1;//成功 public static final int TYPE_RESULT_WARN = 2;//警告 public static final int TYPE_RESULT_INFO = 3;//提示信息 public ResultInfo(){} /** * 消息提示類型 */ private int type; /** * 提示代碼 */ private int messageCode; /** * 提示信息 */ private String message; /** * 提示信息明細列表 */ private List<ResultInfo> details; public List<ResultInfo> getDetails() { return details; } public void setDetails(List<ResultInfo> details) { this.details = details; } /** * 提示消息對應操做的序號,方便用戶查找問題,一般用於在批量提示信息中標識記錄序號 */ private int index; /** * 提交後獲得到業務數據信息從而返回給頁面 */ private Map<String,Object> sysdata = new HashMap<String, Object>(); /** * 構造函數,根據提交信息代碼messageCode獲取提示信息 * @param MESSAGE */ public ResultInfo(final int type,int messageCode,String message){ this.type = type; this.messageCode = messageCode; this.message = message; } public int getMessageCode() { return messageCode; } public void setMessageCode(int messageCode) { this.messageCode = messageCode; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public int getType() { return type; } public void setType(int type) { this.type = type; } public boolean isSuccess(){ if(this.type == TYPE_RESULT_SUCCESS){ return true; } return false; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public Map<String, Object> getSysdata() { return sysdata; } public void setSysdata(Map<String, Object> sysdata) { this.sysdata = sysdata; } }
package yycg.base.process.result; /** * 系統提交結果結果類型 * @author Thinkpad * */ public class SubmitResultInfo { public SubmitResultInfo(ResultInfo resultInfo){ this.resultInfo = resultInfo; } //操做結果信息 private ResultInfo resultInfo; public ResultInfo getResultInfo() { return resultInfo; } public void setResultInfo(ResultInfo resultInfo) { this.resultInfo = resultInfo; } }
使用說明:前端
【1】
ExceptionResultInfo 類繼承了exception,同時添加了resultInfo屬性
resultInfo用來標記異常出錯類型(type)和記錄異常信息(message)
例子:
resultInfo.setType(resultInfo.TYPE_RESULT_FAIL);//0錯誤 1成功 2警告3提示
resultInfo.setMessage("帳號已存在,請從新輸入!");
throw new ExceptionResultInfo(resultInfo);java
【2】
在將json異常信息放回到頁面時使用SubmitResultInfo類
return new SubmitResultInfo(resultInfo);web
package yycg.base.process.exception; import java.io.IOException; import java.lang.reflect.Method; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.http.server.ServletServerHttpResponse; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; import yycg.base.process.result.ExceptionResultInfo; import yycg.base.process.result.ResultInfo; /** * * <p> * Title: ExceptionResolverCustom * </p> * <p> * Description:全局異常處理器 * </p> * <p> * Company: www.itcast.com * </p> * * @author * @date * @version 1.0 */ public class ExceptionResolverCustom implements HandlerExceptionResolver { // json轉換器 // 將異常信息轉json private HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter; // 前端控制器調用此方法執行異常處理 // handler,執行的action類就包裝了一個方法(對應url的方法) @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // 輸出 異常信息 ex.printStackTrace(); // 轉成springmvc底層對象(就是對action方法的封裝對象,只有一個方法) HandlerMethod handlerMethod = (HandlerMethod) handler; // 取出方法 Method method = handlerMethod.getMethod(); // 判斷方法是否返回json // 只要方法上有responsebody註解表示返回json // 查詢method是否有responsebody註解 ResponseBody responseBody = AnnotationUtils.findAnnotation(method, ResponseBody.class); if (responseBody != null) { // 將異常信息轉json輸出 return this.resolveJsonException(request, response, handlerMethod, ex); } /** *1若是上面是可預知異常,type和message都已經設置有值,return ModelandView *直接將可預知異常返回到請求頁面的回調函數,再也不執行如下代碼end *2若是是未知異常,則執行如下代碼,構建未知異常,跳轉到error頁面顯示 */ // 這裏說明action返回的是jsp頁面 // 解析異常 ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex); // 將異常信息在異常頁面顯示 request.setAttribute("exceptionResultInfo", exceptionResultInfo.getResultInfo()); // 轉向錯誤頁面 ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("exceptionResultInfo", exceptionResultInfo.getResultInfo()); modelAndView.setViewName("/base/error");// 邏輯視圖名 return modelAndView; } //------------------------------------------------------------------------------------ // 異常信息解析方法 private ExceptionResultInfo resolveExceptionCustom(Exception ex) { ResultInfo resultInfo = null; if (ex instanceof ExceptionResultInfo) { // 拋出的是系統自定義異常 resultInfo = ((ExceptionResultInfo) ex).getResultInfo(); } else { // 從新構造「未知錯誤」異常 resultInfo = new ResultInfo(); resultInfo.setType(ResultInfo.TYPE_RESULT_FAIL); resultInfo.setMessage("未知錯誤!"); } return new ExceptionResultInfo(resultInfo); } //------------------------------------------------------------------------------------ // 將異常信息轉json輸出 private ModelAndView resolveJsonException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { // 解析異常 (解析返回異常是自定義異常仍是未知異常) ExceptionResultInfo exceptionResultInfo = resolveExceptionCustom(ex); HttpOutputMessage outputMessage = new ServletServerHttpResponse(response); try { //將exceptionResultInfo對象轉成json輸出 jsonMessageConverter.write(exceptionResultInfo, MediaType.APPLICATION_JSON, outputMessage); } catch (HttpMessageNotWritableException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return new ModelAndView(); } public HttpMessageConverter<ExceptionResultInfo> getJsonMessageConverter() { return jsonMessageConverter; } public void setJsonMessageConverter( HttpMessageConverter<ExceptionResultInfo> jsonMessageConverter) { this.jsonMessageConverter = jsonMessageConverter; } }
<!-- json轉換器 --> <bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"> </bean> <!-- 統一異常處理類 --> <bean id="handlerExceptionResolver" class="yycg.base.process.exception.ExceptionResolverCustom"> <!-- 注入一個json轉換器 --> <property name="jsonMessageConverter" ref="jsonMessageConverter" /> </bean>
<init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> <!-- 屏蔽springmvc自動註冊的異常處理器 --> <init-param> <param-name>detectAllHandlerExceptionResolvers</param-name> <param-value>false</param-value> </init-param>
一、自定義全局異常處理器,實現HandlerExceptionResolver接口spring
二、在springmvc.xml配置統一異常處理器。
<!-- json轉換器 -->
<bean id="jsonMessageConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
</bean>
<!-- 統一異常處理類 -->
<bean id="handlerExceptionResolver"
class="yycg.base.process.exception.ExceptionResolverCustom">
<!-- 注入一個json轉換器 -->
<property name="jsonMessageConverter" ref="jsonMessageConverter" />
</bean>json
三、在web.xml中配置:
【前端控制器知道全局異常處理器id爲handlerExceptionResolver
detectAllHandlerExceptionResolvers:
屏蔽自動註冊異常處理器,固定使用bean的id爲handlerExceptionResolver的異常處理器。】
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<init-param>
<param-name>detectAllHandlerExceptionResolvers</param-name>
<param-value>false</param-value>
</init-param>mvc