InitBinder-www6662016com-I8669I44445端分离的形式

「Springboot系列」统一异常处理
InitBinder-www6662016com-I8669I44445端分离的形式
异常处理在日常的web开发中是至关重要的一个环节,关乎着用户与应用之间的交互性是否友好,在日常web开发中发生了异常,往往是需要通过一个统一的异常处理来保证客户端能够收到友好的提示。
方案一:

在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中去;
所以在这里我们使用@ControllerAdvice注解来增强所有的@RequestMapping注解标记的方法

直接上代码:

@RestControllerAdvice
public class MyControllerAdvice {
private final static Logger logger = LoggerFactory.getLogger(MyControllerAdvice.class);br/>@ExceptionHandler
public ResultModel handler(HttpServletRequest req, HttpServletResponse res, Exception e) {
logger.info("Restful Http请求发生异常...");
if (res.getStatus() == HttpStatus.BAD_REQUEST.value()) {
logger.info("修改返回状态值为200");
res.setStatus(HttpStatus.OK.value());
}
if (e instanceof NullPointerException) {
logger.error("代码00:" + e.getMessage(), e);
return ResultModel.fail("发生空指针异常");
} else if (e instanceof IllegalArgumentException) {
logger.error("代码01:" + e.getMessage(), e);
return ResultModel.fail("请求参数类型不匹配");
} else if (e instanceof SQLException) {
logger.error("代码02:" + e.getMessage(), e);
return ResultModel.fail("数据库访问异常");
} else {
logger.error("代码99:" + e.getMessage(), e);
return ResultModel.fail("服务器代码发生异常,请联系管理员");
}
}
}
方案二:

使用AOP技术,Aop就是面向切面编程,这里不去细说aop了
代码实现,返回结果实体

@Databr/>@NoArgsConstructor
@AllArgsConstructor
public class ResultModel<T> {
private boolean success = true;
private String message;
private T entity;
public static <T> ResultModel success(T entity) {
return new ResultModel(true, null, entity);
}
public static <T> ResultModel fail(String message, T entity) {
return new ResultModel(false, message, entity);
}
public static <T> ResultModel fail(String message) {
return fail(message, null);
}
}
Aop:实现

@Componentbr/>@Aspect
public class ControllerAspect {
public static final Logger logger = LoggerFactory.getLogger(ControllerAspect.class);
@Around("execution(public com.wangyu.model.ResultModel com...controller...*(..))")
public Object handleControllerMethod(ProceedingJoinPoint pjp) {
Stopwatch stopwatch = Stopwatch.createStarted();
ResultModel<?> resultModel;
try {
logger.info("执行Controller开始: " + pjp.getSignature() + " 参数:" + Lists.newArrayList(pjp.getArgs()).toString());
resultModel = (ResultModel<?>) pjp.proceed(pjp.getArgs());
logger.info("执行Controller结束: " + pjp.getSignature() + ", 返回值:" + resultModel.toString());
logger.info("耗时:" + stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "(毫秒).");
} catch (Throwable throwable) {
resultModel = handlerException(pjp, throwable);
}
return resultModel;
}
private ResultModel<?> handlerException(ProceedingJoinPoint pjp, Throwable e) {
ResultModel<?> resultModel = null;
if (e instanceof RuntimeException) {
logger.error("RuntimeException{方法:" + pjp.getSignature() + ", 参数:" + pjp.getArgs() + ",异常:" + e.getMessage() + "}", e);
resultModel = ResultModel.fail(e.getMessage());
} else {
logger.error("异常{方法:" + pjp.getSignature() + ", 参数:" + pjp.getArgs() + ",异常:" + e.getMessage() + "}", e);
resultModel = ResultModel.fail(e.getMessage());
}
return resultModel;
}
}
具体测试效果和controller就不再贴出来了,有兴趣的朋友可以自己亲自写一下,测试一下。ps:最近后台写了不少,忙着学习前端Vue.js去了,整个项目准备采用前后端分离的形式,后面会陆续的为大家分享学习心得和笔记,谢谢支持

如有不足之处,欢迎留言,让我们共同进步。如果你觉得有阅读和收藏价值,请关注本人,每天为你分享编程相关知识。

猜你喜欢

转载自blog.51cto.com/14114152/2324894
I