《Spring全局异常处理》从零掌握@ControllerAdvice注解
一、开门见山
在前后端分离框架的大趋势下,前后端基本的职责已经确定。
前端主要负责界面的处理以及基本的判空检验。数据来源则通过vue调用后端发布的接口。
后端的原型还是mvc的模式:
controller |
接受前端请求(entity或者list<entity>),并调用service提供的功能性接口,返回json |
service | 定义接口做实际的业务处理,数据库处理。可以调用微服务接口,可以调用dao层的数据库CURD |
dao | 一般单表操作,利用mybatisplus就可以实现单笔或者批量操作 |
从表格中我们可以看出,service层主要处理业务逻辑,那么就一定会有意想不到的“惊喜”,因此我们一般需要在service层
进行异常处理,并将此异常抛给controller进行处理(因为controller是前后端沟通的桥梁,可以将异常处理后,返回给前端),
就此ControllerAdvice闪亮登场!
二、异常处理流程详解
2.1、定义错误码
路径:i18n/message_zh_CN.properties(国际化文本,此处不做赘述,不懂得尽快去找度娘)
00=操作成功 01=数据库插入数据失败 02=数据库删除数据失败 03=数据库更新数据失败 04=数据库查询数据失败 05=查询结果为空 06=工作流操作失败 07=请求参数异常 08=操作异常
2.2、定义获取中文描述的工具类
@Component public class MessageUtil {
private static MessageSource messageSource; @Autowired public MessageUtil(MessageSource messageSource) { messageSource = messageSource; } public static String get(String msgKey) { try { String message = messageSource.getMessage(msgKey, (Object[])null, LocaleContextHolder.getLocale());
return message; } catch (Exception var2) { return msgKey; } } }
2.3、定义枚举类进行包装
public enum SCodeEnum { SUCCESS("00"), INSERT_ERROR ("01"), DELETE_ERROR("02"), UPDATE_ERROR("03"), SELECT_ERROR("04"), SELECT_EMPTY("05"), OPERATE_FLOWABLE_ERROR("06"), REQUEST_ARGS_ERROR("07"), OPERATE_EXCEPTION("08"); private String code; SCodeEnum(String code) { this.code=code; } public String getCode(){ return this.code; } }
2.4、错误码与错误信息的获取
//获取错误码 SCodeEnum.SUCCESS //获取错误信息 MessageUtil.get(SCodeEnum.SUCCESS.getCode())
2.5、定义自己的异常处理类(统一抛出此异常)
public class BizException extends Exception { public BizException(SCodeEnum codeEum) { super(MessageUtil.get(codeEum.getCode())); super.errorCode = codeEum.getCode(); } }
2.6、定义全局异常处理类,加上ControllerAdvice
@RestControllerAdvice() //当返回是json的时候,利用RestControllerAdvice,类比RestController public class SiteExceptionHandler { //自定义异常 @ExceptionHandler(BizException.class) public Object handleException(HttpServletRequest request, BizException e){ LoggerUtil.error("出现异常======> [{}] ",e); return SResponseUtil.output(SCodeEnum.OPERATE_EXCEPTION, MessageUtil.get(SCodeEnum.OPERATE_EXCEPTION.getCode())); } //spring @Valid判空拦截的异常 @ExceptionHandler(MethodArgumentNotValidException.class) public Object handleException(HttpServletRequest request, MethodArgumentNotValidException e){ LoggerUtil.error("出现异常======> [{}] ",e); String message = e.getBindingResult().getAllErrors().stream().findFirst().get().getDefaultMessage(); return SResponseUtil.output(SCodeEnum.REQUEST_ARGS_ERROR, message); } //当抛出没有拦截的异常的时,就会统一由最高级Exception接管 @ExceptionHandler(Exception.class) public Object handleException(HttpServletRequest request, Exception e){ LoggerUtil.error("出现异常======> [{}] ",e); return SResponseUtil.output(SCodeEnum.OPERATE_EXCEPTION, MessageUtil.get(SCodeEnum.OPERATE_EXCEPTION.getCode())); } }
2.7、service层开始抛异常
throw new BizException(codeEum);
三、每日闲暇时光
3.1、新鲜事
高考结束
3.2、歌曲推荐
北京东路的日子,祝愿考生们即将开始新的旅程。
3.3、影视推荐
超时空接触,如果你也是一名喜欢科幻,热爱探索未知的童鞋。
3.4、每日金句
高考,是人生中唯一一次拿起武器为自己战斗的时刻,或许不能决定你的一生,但可以给你一种权利,选择的权力。-魏平涛
3.5、养眼壁纸
妹子虽好看,没有营养快线,切莫贪杯哦