Spring MVC 統一異常處理


關閉系統級別的 detectAllHandlerExceptionResolvers = false 不加載默認的那三個異常處理器

org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.DefaultHandlerExceptionResolver

<servlet>
    <servlet-name>sample</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/conf/spring-sample.xml</param-value>
    </init-param>
    <init-param>
        <param-name>detectAllHandlerExceptionResolvers</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

添加異常處理BEAN bean handlerExceptionResolver 在Spring的配置文件中添加下面的Bean

<bean id="handlerExceptionResolver" class="....UnifyExceptionHandlerExceptionResolver"/>

創建自己的全局異常處理BEAN 繼承自ExceptionHandlerExceptionResolver

支持默認的 @ExceptionHandler @ControlAdvise

import java.lang.reflect.Field;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;

/**
 * 異常的統一處理  返回錯誤頁面或者JSON
 * @author zln
 *
 */
public class UnifyExceptionHandlerExceptionResolver extends ExceptionHandlerExceptionResolver{
    @SuppressWarnings("unused")
    private Logger logger = LoggerFactory.getLogger( this.getClass() );
    
    @Resource RequestMappingHandlerAdapter requestMappingHandlerAdapter;
    
    @Override
    public void afterPropertiesSet() {
        //設置消息轉換器 以及內容協商管理器
        Field cnm = ReflectionUtils.findField(RequestMappingHandlerAdapter.class, "contentNegotiationManager");
        cnm.setAccessible(true);
        setContentNegotiationManager( (ContentNegotiationManager) ReflectionUtils.getField(cnm, requestMappingHandlerAdapter) );
        setMessageConverters( requestMappingHandlerAdapter.getMessageConverters() );
        
        super.afterPropertiesSet();
    }
    
    /**
     * 重寫 {@code doResolveHandlerMethodException} 以便支持 @ExceptionHandler
     */
    @Override
    protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, 
            HandlerMethod handlerMethod,
            Exception exception) {
        ModelAndView mv = null;
        
        mv =  super.doResolveHandlerMethodException(request, response, handlerMethod, exception);
        if( null != mv ){
            return mv;
        }
        
        if( null != handlerMethod.getMethodAnnotation(ResponseBody.class) ){
            mv = doResolveResponseBodyHandlerMehtod(request, response, handlerMethod, exception);
            
            if( null != mv ){
                return mv;
            }
        }
        
        return doFallbackResolveHandlerMethodException( request, response, handlerMethod, exception );
    }
    
    protected ModelAndView doFallbackResolveHandlerMethodException( HttpServletRequest request, HttpServletResponse response,
            HandlerMethod handlerMethod,
            Exception exception ){
        
        ModelAndView oops = new ModelAndView();
        oops.setViewName("oops");
        
        return oops;
    }
    
    protected ModelAndView doResolveResponseBodyHandlerMehtod(HttpServletRequest request, HttpServletResponse response, 
            HandlerMethod handlerMethod,
            Exception exception) {
        try {
            ModelAndViewContainer mavContainer = new ModelAndViewContainer();
            ServletWebRequest webRequest = new ServletWebRequest(request, response);
            
            String wsResult = null;

            this.getReturnValueHandlers().handleReturnValue(wsResult, handlerMethod.getReturnValueType(wsResult), 
                    mavContainer,
                    webRequest);

            if (mavContainer.isRequestHandled()) {
                return new ModelAndView();
            } else {
/*              ModelAndView mav = new ModelAndView().addAllObjects(mavContainer.getModel());
                mav.setViewName(mavContainer.getViewName());
                if (!mavContainer.isViewReference()) {
                    mav.setView((View) mavContainer.getView());
                }
                return mav;*/
                return null;
            }
        } catch (Exception e) {
            return null;
        }
    }
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM