ControllerAdvice註解的使用

爲了方便對異常的統一管理,spring mvc提供了ControllerAdvice註解對異常進行統一的處理,拿到這些異常信息後,可以做一些處理,比如提供一個統一的web界面查看異常信息,或者普通到異常信息後,發送短信、郵件形式通知到相關人員,可以幫助開發人員快速發現並定位問題,減少以往通過查看線上日誌文件排查問繁瑣鎖耗時的所耗費的時間。下面我跟大家介紹具體步驟。

配置

spring 版本:

<org.springframework-version>4.1.9.RELEASE</org.springframework-version>  

spring-servlet.xml,注意必須開啓註解,即xml要有

<?xml version="1.0" encoding="UTF-8"?>  
<beans:beans xmlns="http://www.springframework.org/schema/mvc"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  

    <!-- DispatcherServlet Context: defines this servlet's request-processing   
        infrastructure -->  

    <!-- Enables the Spring MVC @Controller programming model -->  
    <annotation-driven />  

    <!-- Handles HTTP GET requests for /resources/** by efficiently serving   
        up static resources in the ${webappRoot}/resources directory -->  
    <resources mapping="/resources/**" location="/resources/" />  

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources   
        in the /WEB-INF/views directory -->  
    <beans:bean  
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <beans:property name="prefix" value="/WEB-INF/views/" />  
        <beans:property name="suffix" value=".jsp" />  
    </beans:bean>  
    <context:component-scan base-package="org.as.asjee" use-default-filters="false">  
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
    </context:component-scan>  

</beans:beans> 

異常統一處理類


package org.as.asjee.core.exception;

import java.sql.SQLException;

import javax.servlet.http.HttpServletRequest;

import org.as.asjee.core.log.AsJEELogger;
import org.as.asjee.core.log.AsJEELoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * 捕獲異常統一處理
 * @description TODO
 * @author chen.gs
 * @create date 2016年4月28日
 * @modified by 
 * @modify date
 * @version v1.0
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private final static AsJEELogger LOG = AsJEELoggerFactory.getLogger(GlobalExceptionHandler.class);

    private final static String EXPTION_MSG_KEY = "message";

    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public void handleBizExp(HttpServletRequest request, Exception ex){
        LOG.info("Business exception handler  " + ex.getMessage() );
        request.getSession(true).setAttribute(EXPTION_MSG_KEY, ex.getMessage());
    }

    @ExceptionHandler(SQLException.class)
    public ModelAndView handSql(Exception ex){
        LOG.info("SQL Exception " + ex.getMessage());
        ModelAndView mv = new ModelAndView();
        mv.addObject("message", ex.getMessage());
        mv.setViewName("sql_error");
        return mv;
    }

}

自定義異常類BussinessException.java

package org.as.asjee.core.exception;

/**
 * 業務異常
 * @description TODO
 * @author chen.gs
 * @create date 2016年4月28日
 * @modified by 
 * @modify date
 * @version v1.0
 */
public class BusinessException extends Exception{

    private static final long serialVersionUID = 1L;

    //業務類型
    private String bizType;
    //業務代碼
    private int bizCode;
    //錯誤信息
    private String message;

    public BusinessException(String bizType, int bizCode, String message){
        super(message);
        this.bizType = bizType;
        this.bizCode = bizCode;
        this.message = message;
    }

    public BusinessException(String message){
        super(message);
        this.bizType = "";
        this.bizCode = -1;
        this.message = message;
    }

    public BusinessException(String bizType, String message){
        super(message);
        this.bizType = bizType;
        this.bizCode = -1;
        this.message = message;
    }

    public BusinessException(int bizCode, String message){
        super(message);
        this.bizType = "";
        this.bizCode = bizCode;
        this.message = message;
    }

    public String getBizType() {
        return bizType;
    }

    public void setBizType(String bizType) {
        this.bizType = bizType;
    }

    public int getBizCode() {
        return bizCode;
    }

    public void setBizCode(int bizCode) {
        this.bizCode = bizCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

controller

package org.as.asjee.core.security.web;

import java.sql.SQLException;

import javax.annotation.Resource;

import org.as.asjee.core.exception.BusinessException;
import org.as.asjee.core.security.model.User;
import org.as.asjee.core.security.service.UserService;
import org.as.asjee.core.service.ServiceFacade;
import org.as.asjee.core.web.AbstractController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/security/user")
public class UserController  extends AbstractController<User>{

    @Resource
    private UserService userService;
    @Resource
    private ServiceFacade serviceFacade;

    @RequestMapping("login")
    public String login() { 
        return "login";
    }

    @RequestMapping("login2")
    public String login2() throws Exception {
        throw new SQLException("出錯鳥。。。。。。。。。");
    }   

    @RequestMapping("login3")
    public String login3() throws Exception { 
        throw new BusinessException("業務執行異常");
    }

    //此方法拋出的異常不是由GlobalExceptionHandler處理
    //而是在catch塊處理
    @RequestMapping("login4")
    public String login4() { 
        try {
            throw new BusinessException("業務執行異常");
        } catch (BusinessException e) {
            e.printStackTrace();
        }
        return "login";
    }

}

簡要說明

在Controller中拋出的異常,當沒有被catch處理時,GlobalExceptionHandler中定義的處理方法可以起作用,在方法寫明註解@ExceptionHandler,並註明其異常類即可。此種方法不僅可以作用於Controller,同樣的在DAO層、service層也可,都可以由GlobalExceptionHandler進行處理。此種寫法減少代碼的入侵,值得推薦。
異常的統一處理只是註解ControllerAdvice用處之一,有興趣瞭解更多的,請到spring官網查閱。

發佈了121 篇原創文章 · 獲贊 574 · 訪問量 66萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章