目录
丑陋的try-catch
最近在工作中使用@RestControllerAdvice做了全局异常处理,但是发现spring就算能捕获到所有的异常,我们还是无法友好的提示用户。毕竟我们每个接口的错误提示都不相同,
比如:保存用户失败,查询用户失败等。我们需要对每个接口 try{}catch(){} 才能在错误时进行提示。如图这样的代码看起来非常不友好,大大的降低了代码的可读性
。
aop 中 try-catch
1)要处理以上问题,我想到的第一中解决方案就是使用aop,在接口上使用注解指定该接口出错时的提示内容,并作为aop的切点。所有我们需要添加一个自定义注解
package com.***.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 指定controller发生异常时的注解
* 同时作为aop的切入点
* @author Administrator
*/
@Retention(RetentionPolicy.RUNTIME) //该注解表示生命周期
@Target(ElementType.METHOD)
public @interface ExceptionResultAnn {
String value() default "未知异常";
}
2)我的返回类,请自行修改
package com.***.entity;
import java.io.Serializable;
/**
* 封装返回结果
*/
public class Result implements Serializable{
private boolean flag;//执行结果,true为执行成功 false为执行失败
private String message;//返回结果信息
private Object data;//返回数据
public Result(boolean flag, String message) {
super();
this.flag = flag;
this.message = message;
}
public Result(boolean flag, String message, Object data) {
this.flag = flag;
this.message = message;
this.data = data;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
3)配置切面类
package com.***.aop;
import com.itfenghuang.annotation.ExceptionResultAnn;
import com.itfenghuang.entity.Result;
import com.itfenghuang.exception.MyException;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 切面
* @author Administrator
*/
@Aspect
@Component
public class ExceptionResultAspect {
private static Logger logger = Logger.getLogger(ExceptionResultAspect.class);
@Pointcut("@annotation(com.itfenghuang.annotation.ExceptionResultAnn)")
private void pointcut() {}
@Before("pointcut()")
public void advice(JoinPoint joinPoint) {
}
@Around("pointcut()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
//对要执行的方法进行try-catch,如果出现异常,就将注解中的参数作为错误消息返回给前端
try {
//执行controller
return proceedingJoinPoint.proceed();
} catch (Exception e) {
//获取注解中的消息
MethodSignature sign = (MethodSignature)proceedingJoinPoint.getSignature();
Method method = sign.getMethod();
ExceptionResultAnn annotation = method.getAnnotation(ExceptionResultAnn.class);
String value = annotation.value();
//返回
return new Result(false,value);
}
}
}
4)在controller中的接口上使用
@ExceptionResultAnn("在失败时,这里的消息可以在aop中获取到,用于返回给前端")
@RequestMapping("/test")
public Result test(){
int i = 1 / 0;
return new Result(true,"测试数据");
}