全局异常捕获处理-@ControllerAdvice+@HandleException

涂涂影院管理系统这个demo中有个异常管理的标签,用于捕获 涂涂影院APP用户异常信息 ,有小伙伴好奇,排除APP,后台端的是如何处理全局异常的,故项目中的实际应用已记之。

关于目前的异常处理

在使用全局异常处理之前,就目前我们是如何处理程序中的异常信息的呢?

throws Exception + try-catch

怎么讲?

在我们目前项目中,往往事务发生在 Service 层,因为会牵扯到调用 Dao 跟数据库打交道,当数据库操作失败时,会让 Service 层抛出运行时异常,Spring 事物管理器就会进行回滚。

Service 抛出异常,那么 Controller 必然要去捕获,处理异常,所以,try-catch 就出现了。

看一下Service:

public interface ServiceI{## 保存实体的方法public Serializable save(Entity entity) throws Exception;
}

看一下Controller的某个调用方法:

@PostMapping(value = "")
public AppResponse add(@RequestBody Entity entity, Errors errors){AppResponse resp = new AppResponse();try {Entity endity = new Entity();endity.setXxx();ServiceI.save(dog);## 返回数据resp.setData(newDog);}catch (BusinessException e){resp.setFail(e.getMessage());}catch (Exception e){resp.setFail("操作失败!");}return resp;
}

看上去也没什么别就,但是一个类中出现大面积的 try-catch ,就显得非常难看且冗余。

如果使用 @ControllerAdvice + @ExceptionHandler 进行全局的 Controller 层异常处理,只要设计得当,就再也不用在 Controller 层进行 try-catch 了。

书写全局异常处理

1. @ControllerAdvice注解

定义全局异常处理类,@RestControllerAdvice 为 @ResponseBody + @ControllerAdvice

@Slf4j
@RestControllerAdvice
public class RestCtrlExceptionHandler {}
2. @ExceptionHandler注解

声明异常处理方法,方法 handleException() 就会处理所有 Controller 层抛出的 Exception 及其子类的异常,这是最基本的用法了。

    @ExceptionHandler(Exception.class)@ResponseStatus(value = HttpStatus.OK)public Result<Object> handleException(Exception e) {String errorMsg = "Exception";if (e!=null){errorMsg = e.getMessage();log.error(e.toString());}return new ResultUtil<>().setErrorMsg(500, errorMsg);}

结合上边1、2组合一下:

@Slf4j
@RestControllerAdvice
public class RestCtrlExceptionHandler {@ExceptionHandler(TmaxException.class)@ResponseStatus(value = HttpStatus.OK)public Result<Object> handleXCloudException(TmaxException e) {String errorMsg = "Tmax exception";if (e!=null){errorMsg = e.getMsg();log.error(e.toString());}return new ResultUtil<>().setErrorMsg(500, errorMsg);}@ExceptionHandler(Exception.class)@ResponseStatus(value = HttpStatus.OK)public Result<Object> handleException(Exception e) {String errorMsg = "Exception";if (e!=null){errorMsg = e.getMessage();log.error(e.toString());}return new ResultUtil<>().setErrorMsg(500, errorMsg);}
}

看一下 handleXCloudException() 方法

通常我们需要抛出我们自定义异常,而不是一有异常就全部进入 handleException 中,该方法中 TmaxException 即为我们自定义的异常。

@Data
public class TmaxException extends RuntimeException {private String msg;public TmaxException(String msg){super(msg);this.msg = msg;}
}

这样,我们就可以在 Controller 中抛出我们定义的异常了,比如:

throw new TmaxException("连接ES失败,请检查ES运行状态");

如果文章有错的地方欢迎指正,大家互相留言交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:niceyoo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414442.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习(2791):实现上拉加载更多

判断页面是否有十条数据 没有 则消失

使用DOM4J解析XML时非法字符Exception

最近在做简单的解析XML的工作&#xff0c;我使用的是DOM4J来解析&#xff0c;可以说很方便了&#xff0c;在加上使用XPATH来具体确定XML中特定元素下的位置&#xff0c;更加便捷了 可是在使用XML解析是却遇到了这样的问题&#xff1a; org.xml.sax.SAXParseException: An inval…

2019金球奖——梅西

在公元2019年12月3日&#xff0c;梅西加冕金球奖六冠王&#xff0c;今天我是梅西&#xff0c;今天属于梅西&#xff0c;祝贺梅西&#xff01; 王者气质 十全十美 实至名归 六金闪耀 蓦然回首&#xff0c;已是十年信仰

定时任务 Scheduled quartz

在项目应用中往往会用到任务定时器的功能&#xff0c;比如某某时间&#xff0c;或者多少多少秒然后执行某个骚操作等。 spring 支持多种定时任务的实现&#xff0c;其中不乏自身提供的定时器。 接下来介绍一下使用 spring 的定时器和使用 quartz 定时器。 前言 spring 自身提供…

前端学习(2792):下拉刷新

开启下拉刷新 延迟下拉刷新 解决下拉刷新 传递callback有就刷新 无就不刷新

Android 打开另一个APP,H5打开APP方法,打开淘宝、京东、天猫、拼多多。需求、商品详情或优惠券页面

1、在待打开的APP注册可被外APP调用的activity <activity android:name".TwoActivity"><intent-filter ><action android:name"android.intent.action.VIEW" /><category android:name"android.intent.category.DEFAULT"/…

Android 获取短信验证码,自动填充

1、申请权限 <uses-permission android:name"android.permission.RECEIVE_SMS" /> <uses-permission android:name"android.permission.READ_SMS" /> API>23动态申请权限 private static final String[] authBaseArr {//申请类型Manife…

网络请求之优化参数添加工具类自定义Map类

导入依赖&#xff1a; implementation com.squareup.okhttp3:okhttp:3.4.1 调用方法&#xff1a; File file new File("");HttpParams params new HttpParams(); params.put("mobile", "22"); params.put("password", 33); params.…

android studio 导入依赖报错——Could not find com.xxx,(# fields: 66338 > 65536)

替换项目build.gradle即可 buildscript {repositories {maven{url https://maven.aliyun.com/repository/google}maven{url https://maven.aliyun.com/repository/jcenter} // maven{url https://maven.aliyun.com/nexus/content/groups/public}maven { url "http…

spring-boot-starter-parent

一、你的项目 pom.xml 中有这段代码吗 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.5.RELEASE</version><relativePath/> </parent>idea &…

java学习--基础知识阶段性总结--网络编程

网络编程&#xff1a; 端口&#xff1a; 物理端口&#xff1a; 逻辑端口&#xff1a;用于标识进程的逻辑地址&#xff0c;不同进程的标识&#xff1b;有效端口&#xff1a;0~65535&#xff0c;其中0~1024系统使用或保留端口。 java 中ip对象&#xff1a;InetAddress. import ja…

android 加载显示富文本——TextView显示富文本和WebView显示富文本,WebView显示图片适配屏幕宽度

"connectDeviceLedStatus_dcq":"请先确认设备指示灯为 <strong><font color\"#088A01\">绿灯闪烁</font></strong> 状态。", tv_dev_one_tip1.setText(Html.fromHtml(LangComm.getString("feeder_ble_bind_guide_t…

项目集成Spring Security

前言 之前写的 涂涂影院管理系统 这个 demo 是基于 shiro 来鉴权的&#xff0c;项目前后端分离后&#xff0c;显然集成 Spring Security 更加方便一些&#xff0c;毕竟&#xff0c;都用 Spring 了&#xff0c;权限管理当然 Spring Security. 花了半天时间整理的笔记&#xff0…

android 使用AIDL实现进程间通讯

一、创建服务端 1、首先创建AIDL文件 2、创建service&#xff0c;绑定AIDL接口 3、配置service <service android:name".AidlService"android:enabled"true"android:exported"true"><intent-filter android:priority"1000"&…