原文地址:http://blog.csdn.net/weililansehudiefei/article/details/73691294
@ControllerAdvice注解的类,会被作用于@RequesMapping注解的方法上。
先来看看它的基本实现
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Component
- public @interface ControllerAdvice {
被Component注解,说明可以通过<context:component-scan>来扫描到。
在Web开发中,最基本的都是从Controller到Service再到DAO。在开发的过程中,会需要处理各种异常。Service异常往上抛,如果上层没有try-catch,就会出异常。而通过ControllerAdvice 注解,我们可以使得所有异常在controller进行处理,而开发过程中更加专注于业务的处理。
首先定义一个全局异常的处理类
- 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,
- 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);}
- }