自定義SimpleMappingExceptionResolver實現個性化的異常處理

Spring MVC 的SimpleMappingExceptionResolver是一個簡單的異常處理bean,說他簡單是因爲SimpleMappingExceptionResolver只能獲得內置的異常信息,用戶無法將自定義的異常信息帶到頁面上供用戶查看,且SimpleMappingExceptionResolver不支持ajax的異常處理。爲了能夠讓異常體制更具個性化。我們常做的方法是實現HandlerExceptionResolver接口自定義自己的異常處理器。下面介紹另外一種方法:重寫SimpleMappingExceptionResolver來實現異常的個性化。

SimpleMappingExceptionResolver異常處理其核心是doResolveException()

protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) {
   String viewName = this.determineViewName(ex, request);
   if(viewName != null) {
       Integer statusCode = this.determineStatusCode(request, viewName);
       if(statusCode != null) {
           this.applyStatusCodeIfPossible(request, response, statusCode.intValue());
       }

       return this.getModelAndView(viewName, ex, request);
   } else {
       return null;
   }
}
所以我們要做的就是重寫這個方法

package com.me.common.exception;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import java.io.IOException;
import java.util.Properties;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.me.endpoint.GrantResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
public class MyExceptionResolver extends SimpleMappingExceptionResolver {


   private String defaultErrorView;

   private Properties exceptionMappings;

   public MyExceptionResolver() {
   }

   @Override
   public void setDefaultErrorView(String defaultErrorView) {
       this.defaultErrorView = defaultErrorView;
       super.setDefaultErrorView(defaultErrorView);
   }

   @Override
   public void setExceptionMappings(Properties exceptionMappings) {
       this.exceptionMappings = exceptionMappings;
       super.setExceptionMappings(exceptionMappings);
   }

   @Override
   protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) {
       boolean isAjax = this.isJsonRequest(handler);
       return isAjax?this.jsonExceptionHandler(response, ex):this.generalExceptionHandler(request, response, ex);
   }

   private boolean isJsonRequest(Object handler) {
       HandlerMethod method = (HandlerMethod)handler;
       ResponseBody body = (ResponseBody)method.getMethodAnnotation(ResponseBody.class);
       return body != null;
   }
   
     //ajax異步請求
   private ModelAndView jsonExceptionHandler(HttpServletResponse response, Exception e) {

       ServletOutputStream stream = null;

       try {
           response.setContentType("application/json");
           response.setCharacterEncoding("UTF-8");
           response.setHeader("Cache-Control", "no-cache, must-revalidate");
           stream = response.getOutputStream();
           String errorMsg  =  "系統出錯了";
           if(e instanceof   GenericException  || e instanceof  EcouponException){
               errorMsg  =  e.getMessage();
           }
           stream.write(JSON.toJSONBytes(new GrantResult("faild", errorMsg), new SerializerFeature[]{SerializerFeature.QuoteFieldNames}));
       } catch (Exception var16) {

       } finally {
           if(stream != null) {
               try {
                   stream.close();
               } catch (IOException var15) {
                   var15.printStackTrace();
               }
           }
       }
       return new ModelAndView();
   }

     //普通請求
   private ModelAndView generalExceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) {
       String errorLog = String.format("web請求[%s]發生異常:%s", new Object[]{request.getServletPath(), ex.getMessage()});
       this.logger.error(errorLog, ex);
       ModelAndView mav = new ModelAndView();
       String errorMsg  =  "系統出錯了";
       if(ex instanceof   GenericException  || ex instanceof  EcouponException){
           errorMsg  =  ex.getMessage();
       }
       mav.addObject("msg", errorMsg);
       String name = ex.getClass().getName();
       String path = this.exceptionMappings.getProperty(name);
       String wrapperPath = StringUtils.isEmpty(path)?defaultErrorView:path;
       mav.setViewName(wrapperPath);
       return mav;
   }


}
最後配置該bean:

<bean class="com.me.common.exception.XExceptionResolver">
       <!-- view name resolved using bean of type InternalResourceViewResolver (declared in mvc-view-config.xml) -->
       <property name="defaultErrorView" value="exception"/>
       <!-- needed otherwise exceptions won't be logged anywhere -->
       <property name="exceptionMappings">
           <props>
               <prop key="com.me.common.exception.GenericException">error/error</prop>
               <prop key="com.me.common.exception.EcouponException">error/error</prop>
               <prop key="java.lang.Exception">error/error</prop>
           </props>
       </property>
   </bean>

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