對Controller層方法進行統一異常處理
阿新 • • 發佈:2021-12-09
兩種方案
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; } }