springboot+aop+自定义注解,打造通用的全局异常处理和参数校验切面(通用版)
2019-03-11 15:29
1036 查看
一.引入相应的maven依赖
[code]<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>
二.自定义参数校验注解
[code]/** * @Author: guandezhi * @Date: 2019/3/11 13:07 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ParamValidate { String value() default ""; }
三.自定义异常切面
[code]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); } } } } } }
四.自定义全局异常处理器
[code]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如下:
[code]/** * @Author: guandezhi * @Date: 2019/3/11 12:14 */ @Data public class ResultVo<T> { private String resultCode; private String resultMsg; private T data; }
五.在需要校验入参的controller方法上加上自定义注(@ParamValidate)
[code]/** * @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类如下:
[code]/** * @Author: guandezhi * @Date: 2019/3/11 12:19 */ @Data public class User { @NotNull(message = "用户名不能为空") private String name; @NotNull(message = "手机号不能为空") private String mobile; }
六.测试一下
1.当入参为空值时
[code]
1.当程序有异常时
相关文章推荐
- Spring Boot 全局异常处理 与 Hibernate Validator校验框架整合
- 使用Spring Boot的AOP处理自定义注解
- SpringBoot 通过自定义注解实现AOP切面编程实例
- Springboot 自定义注解 AOP切面获取操作日志
- 使用SpringBoot通过自定义注解+AOP+全局异常处理实现参数统一非空校验
- springBoot注解大全JPA注解springMVC相关注解全局异常处理
- 详解使用Spring Boot的AOP处理自定义注解
- 用AOP拦截自定义注解并获取注解属性与上下文参数(基于Springboot框架)
- Spring Web利用切面统一处理参数校验异常的方法
- spring boot 全局统一格式返回自定义异常信息
- SpringAOP使用入门,如何对自定义的注解进行切面编程
- Spring Boot @ControllerAdvice 处理全局异常,返回固定格式Json
- spring aop事务通知(切面异常处理)
- SpringBoot学习历程(4)->全局异常的处理
- Spring-Boot--日志操作全局异常捕获消息处理☞日志控制台输出+日志文件记录
- Spring Boot全局异常处理
- springboot aop 自定义注解方式实现一套完善的日志记录(完整源码)
- SpringBoot自定义注解获取参数和值
- 轻松实现SpringBoot项目异常全局处理
- 利用反射打造自定义注解,自动校验或处理数据