您的位置:首页 > 编程语言 > Java开发

springMVC使用@ControllerAdvice实现异常处理

2017-11-19 10:32 435 查看
原文地址:http://blog.csdn.net/weililansehudiefei/article/details/73691294

@ControllerAdvice注解的类,会被作用于@RequesMapping注解的方法上。

先来看看它的基本实现

[java]
view plain
copy

@Target(ElementType.TYPE)  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
@Component  
public @interface ControllerAdvice {  

被Component注解,说明可以通过<context:component-scan>来扫描到。
在Web开发中,最基本的都是从Controller到Service再到DAO。在开发的过程中,会需要处理各种异常。Service异常往上抛,如果上层没有try-catch,就会出异常。而通过ControllerAdvice 注解,我们可以使得所有异常在controller进行处理,而开发过程中更加专注于业务的处理。

首先定义一个全局异常的处理类

[java]
view plain
copy

package com.creditease.microloan.mil.loanrepay.exception.handler;  
  
import com.alibaba.fastjson.JSONException;  
import com.alibaba.fastjson.JSONObject;  
import com.creditease.microloan.mil.loanrepay.exception.*;  
import org.slf4j.Logger;  
import org.slf4j.LoggerFactory;  
import org.springframework.web.bind.MissingServletRequestParameterException;  
import org.springframework.web.bind.annotation.ControllerAdvice;  
import org.springframework.web.bind.annotation.ExceptionHandler;  
import org.springframework.web.bind.annotation.ResponseBody;  
  
import javax.servlet.http.HttpServletRequest;  
  
/** 
 * 全局异常处理类 
 * <p> 
 * Created by Kong on 17/6/12. 
 */  
@ControllerAdvice  
public class GlobalExceptionHandler {  
  
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);  
  
    /** 
     * 接口有参数未传 
     */  
    @ExceptionHandler(value = MissingServletRequestParameterException.class)  
    @ResponseBody  
    public JSONObject missActionParam(HttpServletRequest req, MissingServletRequestParameterException e) throws Exception {  
        return makeErrorObj("接口有参数未传", req, e);  
    }  
  
    /** 
     * 加密解密错误 
     */  
    @ExceptionHandler(value = CryptException.class)  
    @ResponseBody  
    public JSONObject cryptError(HttpServletRequest req, CryptException e) throws Exception {  
        return makeErrorObj("加密解密有误", req, e);  
    }  
  
    /** 
     * 数字格式错误 
     */  
    @ExceptionHandler(value = NumberFormatException.class)  
    @ResponseBody  
    public JSONObject numberFormatError(HttpServletRequest req, NumberFormatException e) throws Exception {  
        return makeErrorObj("数字格式错误", req, e);  
    }  
  
    /** 
     * JSON格式解析错误 
     */  
    @ExceptionHandler(value = JSONException.class)  
    @ResponseBody  
    public JSONObject jsonError(HttpServletRequest req, JSONException e) throws Exception {  
        return makeErrorObj("JSON格式解析错误", req, e);  
    }  
  
    /** 
     * 服务器内部错误 
     */  
    @ExceptionHandler(value = NullPointerException.class)  
    @ResponseBody  
    public JSONObject nullError(HttpServletRequest req, NullPointerException e) throws Exception {  
        return makeErrorObj("服务器内部错误", req, e);  
    }  
  
    /** 
     * HTTP请求外部服务失败 
     */  
    @ExceptionHandler(value = HTTPConnException.class)  
    @ResponseBody  
    public JSONObject requestError(HttpServletRequest req, HTTPConnException e) throws Exception {  
        return makeErrorObj("HTTP请求外部服务失败", req, e);  
    }  
  
    /** 
     * 绑卡错误 
     */  
    @ExceptionHandler(value = CardException.class)  
    @ResponseBody  
    public JSONObject payError(HttpServletRequest req, CardException e) throws Exception {  
        return makeErrorObj("绑卡错误", req, e);  
    }  
  
    /** 
     * 支付失败 
     */  
    @ExceptionHandler(value = PayException.class)  
    @ResponseBody  
    public JSONObject payError(HttpServletRequest req, PayException e) throws Exception {  
        return makeErrorObj("支付失败", req, e);  
    }  
  
    /** 
     * 第三方支付API返回错误 
     */  
    @ExceptionHandler(value = ThirdPartyPaymentException.class)  
    @ResponseBody  
    public JSONObject thirdPayError(HttpServletRequest req, ThirdPartyPaymentException e) throws Exception {  
        return makeErrorObj("第三方支付API返回错误", req, e);  
    }  
  
    /** 
     * 查询还款计划错误 
     */  
    @ExceptionHandler(value = RepaymentScheduleException.class)  
    @ResponseBody  
    public JSONObject scheduleError(HttpServletRequest req, RepaymentScheduleException e) throws Exception {  
        return makeErrorObj("查询还款计划错误", req, e);  
    }  
  
    /** 
     * 未知错误 
     */  
    @ExceptionHandler(value = Exception.class)  
    @ResponseBody  
    public JSONObject scheduleError(HttpServletRequest req, Exception e) throws Exception {  
        return makeErrorObj("未知错误", req, e);  
    }  
  
    /** 
     * 构造错误信息 
     * 
     * @param msg 错误描述 
     * @param e   异常信息 
     * @return 
     */  
    private JSONObject makeErrorObj(String msg, HttpServletRequest req, Exception e) {  
        JSONObject obj = new JSONObject();  
        obj.put("status", "fail");  
        obj.put("msg", msg + " (" + e.getMessage() + ")");  
        JSONObject logObj = new JSONObject();  
        logObj.put("status", "fail");  
        logObj.put("msg", msg);  
        logObj.put("error", e.getMessage());  
        logObj.put("url", req.getRequestURL());  
        logObj.put("field", req.getParameterMap());  
        logger.error(logObj.toJSONString(), e);  
        return obj;  
    }  
  
}  

通过注解@ExceptionHandler指定异常类型,当被@RequestMapping注解的方法抛出相应的类的异常,就执行相应的异常处理逻辑。
当然我们需要自异常处理类型,比如CryptException,

[java]
view plain
copy

package com.creditease.microloan.mil.loanrepay.exception;  
  
/** 
 * Created by weili on 17/6/19. 
 */  
public class CryptException extends RuntimeException{  
  
    public CryptException(String message){super(message);}  
  
    public CryptException(String message,Throwable cause){super(message,cause);}  
  
    public CryptException(Throwable cause){super(cause);}  
}  

当然可以自定义多种异常的类型,然后在GlobalExceptionHandler.java中进行处理。这样整个工程的所有的所有异常被集中到一个地方,方便增加和删除,也极大的方便业务的开发。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐