Spring中的異常處理(兼顧AJAX和FORM)

沈子平發表於2017-06-07

總結了一下在使用SPRING開發過程中使用的異常處理方式,查詢了一些資料,並在此作為記錄。

統一異常處理-使用預設Resolver

使用SimpleMappingExceptionResolver進行處理,這樣controller層不需要捕獲異常,Spring框架會進行處理。SimpleMappingExceptionResolver是spring的預設實現,但是無法處理AJAX的異常解析

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
   <property name="defaultErrorView" value="error"></property>
   <property name="exceptionAttribute" value="ex"></property>
   <property name="exceptionMappings">
       <props>
           <prop key="IOException">exception/ioexception</prop>
           <prop key="SQLException">exception/dbexception</prop>
       </props>
   </property>
</bean>

統一異常處理- 使用自定義異常處理器

* 新建自定義異常處理器
public class MyExceptionHandler implements HandlerExceptionResolver{
    public ModelAndView resolveException(HttpServletRequest request , HttpServletResponse response,Object handler,Exception ex){
        Map<String,Object> model = new HashMap<String , Object>();
        model.put("ex",ex);
        if(ex instanceof ExceptionA){
            return new ModelAndView("exception/exception_a",model);
        }else if(ex instanceof ExceptionB){
            return new ModelAndView("exception/exception_b",model);
        }else{
            return new ModelAndView("exception/exception_a",model);
        }
    }
}
* 新建自定義異常頁面
* bean宣告
<bean id="exceptionHandler" class="com.springapp.exception.MyExceptionHandler"></bean>

統一異常處理-使用@ExceptionHandler註解

* 在Controller的基類中宣告方法,這種方法無需任何配置(當然要註解掃描)
@ExceptionHandler
public String expaaa(HttpServletRequest request, Exception ex) {
    request.setAttribute("ex", ex);
    if(ex instanceof ExceptionA){
        return "exception/exception_a";
    }else if(ex instanceof ExceptionB){
        return "exception/exception_b";
    }else{
        return "exception/exception_a";
    }
}
* 其他Controller繼承上面的基類

統一異常處理-未捕獲異常的處理
在web.xml中定義

<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/500.jsp</location>
</error-page>
<error-page>
    <error-code>500</error-code>
    <location>/500.jsp</location>
</error-page>
<error-page>
    <error-code>404</error-code>
    <location>/404.jsp</location>
</error-page>

大一統-包含表單和AJAX異常處理

* 增加自定義異常處理器,同時如果是AJAX請求,會返回對應的錯誤回應

public class GlobalExceptionResolver extends SimpleMappingExceptionResolver {
    protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response,Object handler, Exception ex){
        String viewName = determineViewName(ex,request);
        response.setCharacterEncoding("UTF-8");
        if(viewName!=null){
            if (!(request.getHeader("accept").contains("application/json")  ||
                    ( request.getHeader("X-Requested-With")!= null  && request.getHeader("X-Requested-With").contains("XMLHttpRequest") ) )) {
                Integer statusCode = determineStatusCode(request,viewName);
                if(statusCode !=null){
                    applyStatusCodeIfPossible(request,response,statusCode);
                }
                System.out.println("JSP Format Return" + viewName);
                return getModelAndView(viewName,ex,request);

            }else{
                try{
                    PrintWriter writer = response.getWriter();
                    writer.write(ex.getMessage());
                    writer.flush();
                }catch(IOException e){
                    e.printStackTrace();
                }
                System.out.println("JSP Format Return" + viewName);
                return null;
            }
        }else{
            return null;
        }
    }
}
* 配置exceptionresolver
<bean id="exceptionResolver" class="com.springapp.exception.GlobalExceptionResolver">
    <!-- 定義預設的異常處理頁面,當該異常型別的註冊時使用 -->
    <property name="defaultErrorView" value="error"></property>
    <!-- 定義異常處理頁面用來獲取異常資訊的變數名,預設名為exception -->
    <property name="exceptionAttribute" value="ex"></property>
    <!-- 定義需要特殊處理的異常,用類名或完全路徑名作為key,異常也頁名作為值 -->
    <property name="exceptionMappings">
        <props>
            <prop key="IOException">exception/ioexception</prop>
            <prop key="java.sql.SQLException">exception/dbexception</prop>
            <prop key="com.springapp.exception.ExceptionA">exception/exception_a</prop>
            <prop key="com.springapp.exception.ExceptionB">exception/exception_b</prop>
        </props>
    </property>

</bean>
* DONE

相關文章