• @ControllerAdvice是一个@Component,用于定义@ExceptionHandler,@InitBinder和@ModelAttribute方法,适用于所有使用@RequestMapping方法。
  • Spring4之前,@ControllerAdvice在同一调度的Servlet中协助所有控制器。Spring4已经改变:@ControllerAdvice支持配置控制器的子集,而默认的行为仍然可以利用。
  • 在Spring4中, @ControllerAdvice通过annotations(), basePackageClasses(), basePackages()方法定制用于选择控制器子集。

一般配合@ExceptionHandler来处理自定义异常。

package com.demo;

import com.demo.enums.CodeEnum;
import com.demo.exception.BizException;
import com.demo.response.ResponseData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 程序异常统一返回
 * @author baichuan
 * @date 2019/01/02
 */

@ControllerAdvice
public class ExceptionController {

    private static final Logger log = LoggerFactory.getLogger("ERROR_LOG");

    /**
     * 业务异常
     * @param be
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    @ResponseBody
    public ResponseData bizException(BizException be) {
        log.error("occur an bizException: ", be);
        return ResponseData.fail(be.getCode(), be.getMsg());
    }

    /**
     * 请求参数异常
     * @param me
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseData methodArgumentNotValidException(MethodArgumentNotValidException me) {
        log.error("occur an methodArgumentNotValidException: ", me);
        return ResponseData.fail(CodeEnum.PARAM_INVALIDATE.getCode(), me.getBindingResult().getFieldErrors().get(0).getDefaultMessage());
    }

    /**
     * 默认异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = Throwable.class)
    @ResponseBody
    public ResponseData defaultError(Exception e) {
        log.error("occur an exception: ", e);
        return ResponseData.toSystemError();
    }
}