springboot+aop+自定義注解,打造通用的全局異常處理和參數校驗切面(通用版)


一.引入相應的maven依賴

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

 


二.自定義參數校驗注解

/**
* @Author: guandezhi
* @Date: 2019/3/11 13:07
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ParamValidate {
String value() default "";
}

  


三.自定義異常切面

package com.gdz.paramvalidate.aspect;

import com.gdz.paramvalidate.annotation.ParamValidate;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;

import java.lang.reflect.Method;
import java.util.List;

/**
* 異常處理切面
* @Author: guandezhi
* @Date: 2019/3/11 13:03
*/
@Slf4j
@Aspect
@Component
public class ExceptionAspect {

@Before("@annotation(com.gdz.paramvalidate.annotation.ParamValidate)")
public void before(JoinPoint jp) throws Exception {
doBefore(jp);
}

private void doBefore(JoinPoint jp) throws Exception {
if (getParamValidate(jp) == null) {return;}
Object[] args = jp.getArgs();
if (args == null) {return;}
//將異常格式化成通用格式
formateException(args); 
}

private ParamValidate getParamValidate(JoinPoint jp) {
MethodSignature methodSignature = (MethodSignature) jp.getSignature();
Method method = methodSignature.getMethod();
return method.getAnnotation(ParamValidate.class);
}

private void formateException(Object[] args) throws Exception {
for (Object arg : args) {
if (arg instanceof BindingResult) {
BindingResult result = (BindingResult) arg;
if (result != null && result.getErrorCount() > 0) {
List<ObjectError> errors = result.getAllErrors();
String errorMsg = "";
for (ObjectError error : errors) {
if (error instanceof FieldError) {
FieldError fe = (FieldError) error;
errorMsg = String.format("%s:%s", fe.getField(), error.getDefaultMessage());
} else {
errorMsg = String.format("%s:%s ", error.getCode(), error.getDefaultMessage());
}
log.error(errorMsg);
throw new Exception(errorMsg);
}
}
}
}
}

}

  


四.自定義全局異常處理器

package com.gdz.paramvalidate.exception;

import com.gdz.paramvalidate.bean.ResultVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
* 全局異常處理
*
* @Author: guandezhi
* @Date: 2019/3/11 14:43
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {


@ResponseBody
@ExceptionHandler(value = Exception.class)
public ResultVo<Object> handleException(Exception e) {
String errorMsg = "";
if (e instanceof NullPointerException) {
errorMsg = "參數空指針異常";
} else if (e instanceof HttpMessageNotReadableException) {
errorMsg = "請求參數匹配錯誤," + e.getLocalizedMessage();
} else {
errorMsg = e.getMessage();
}
log.error(String.format("請求異常[%s]", e));

ResultVo<Object> resultVo = new ResultVo<>();
resultVo.setResultCode("501");
resultVo.setResultMsg(errorMsg);
return resultVo;
}
}
其中的resultVo如下:

/**
* @Author: guandezhi
* @Date: 2019/3/11 12:14
*/
@Data
public class ResultVo<T> {

private String resultCode;

private String resultMsg;

private T data;

}

  

五.在需要校驗入參的controller方法上加上自定義注(@ParamValidate)

/**
* @Author: guandezhi
* @Date: 2019/3/11 12:15
*/
@Slf4j
@RequestMapping("/user")
@RestController
public class UserController {

@ParamValidate
@RequestMapping("/addUser")
public String addUser(@RequestBody @Valid User user, BindingResult result) throws Exception {
int i = 1 / 0;
return "success";
}
}

  


這里必須加上@ParamValidate  @Valid這兩個注解才能生效

其中User類如下:

/**
* @Author: guandezhi
* @Date: 2019/3/11 12:19
*/
@Data
public class User {

@NotNull(message = "用戶名不能為空")
private String name;

@NotNull(message = "手機號不能為空")
private String mobile;
}

  


六.測試一下

1.當入參為空值時

 

 

 
1.當程序有異常時

 

 

代碼地址:https://github.com/dezhiguan/GlobalExceptionHandler
---------------------
作者: guandezhi
來源:CSDN
原文:https://blog.csdn.net/qq_35859844/article/details/88394376
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM