統一的異常處理和自定義的全局異常處理器的配置使用

統一的異常處理和自定義的全局異常處理器的配置使用

1、統一的異常處理

一、自定義異常處理類,繼承了exception

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

 

2、自定義全局異常處理器,springmvc 提供接口:HandlerExceptionResolver

一、自定義的異常處理器類,實現接口:handlerExceptionResolver

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;
    }

}

 

二、配置

  ①在springmvc.xml文件中配上json轉換器(spring-web jar提供),並注入上面自定義的異常處理器類中,用於異常信息轉換爲json

 

 <!-- 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>
    

 

 ②在web.xml中聲明屏蔽默認的異常處理器,使自定義的異常處理器生效

<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

相關文章
相關標籤/搜索