1. 程式人生 > 其它 >對Controller層方法進行統一異常處理

對Controller層方法進行統一異常處理

兩種方案

1、使用 @ControllerAdvice (或@RestControllerAdvice), @ExceptionHandler 註解實現;
2、使用AOP技術實現;

  • 1、使用 @ControllerAdvice (或@RestControllerAdvice), @ExceptionHandler 註解實現;
package com.zl.securitytest.config;

import com.zl.securitytest.common.Result;
import com.zl.securitytest.common.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
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;

import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 * 統一異常處理
 *
 * @author zhang
 * @date 2021-12-09 17:07
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler({Exception.class})
    @ResponseBody
    public Result<?> resolveException(Exception e) {
        // 繫結引數校驗
        BindingResult bindingResult = this.argumentNotValidHandler(e);
        if (!Objects.isNull(bindingResult)) {
            List<ObjectError> allErrors = bindingResult.getAllErrors();
            Iterator var4 = allErrors.iterator();
            if (var4.hasNext()) {
                ObjectError error = (ObjectError) var4.next();
                log.error(error.getDefaultMessage());
                return Result.failed(error.getDefaultMessage());
            } else {
                return Result.failed(e.getMessage());
            }
        } else {
            log.error(e.getMessage(), e);
            return Result.failed(ResultCode.FAILED.CODE, ResultCode.FAILED.MSG);
        }
    }

    /**
     * 引數驗證異常判斷
     *
     * @param e
     * @return
     */
    private BindingResult argumentNotValidHandler(Exception e) {
        if (e instanceof MethodArgumentNotValidException) {
            return ((MethodArgumentNotValidException) e).getBindingResult();
        } else {
            return e instanceof BindException ? ((BindException) e).getBindingResult() : null;
        }
    }
}

  • 2、 使用AOP技術實現;
package com.zl.securitytest.config;

import com.zl.securitytest.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 統一異常處理
 *
 * @author zhang
 * @date 2021-12-09 17:11
 */
@Aspect
@Component
@Order(1)
@Slf4j
public class GlobalExceptionAspectHandler {
    private static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Pointcut("@within(org.springframework.web.bind.annotation.RestController)")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint point) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        long b = System.currentTimeMillis();
        Object[] args = point.getArgs();
        String now = LocalDateTime.now().format(dateTimeFormatter);

        Object result;
        try {
            // 執行方法
            result = point.proceed(args);
        } catch (Throwable var10) {
            Result<Object> failed = Result.failed("網路請求失敗,請稍後再試!");
            result = failed;
            log.error(GlobalExceptionAspectHandler.class.getName(), var10);
        }
        long e = System.currentTimeMillis();
        System.out.println(now + ": 遠端主機: " + request.getRemoteAddr() + " --> 請求介面(" + request.getRequestURL() + ")執行耗時:" + (e - b) + "ms");
        return result;
    }
}