前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringBoot实战 之 异常处理篇

SpringBoot实战 之 异常处理篇

作者头像
庞小明
发布于 2018-03-07 08:31:09
发布于 2018-03-07 08:31:09
1.8K00
代码可运行
举报
文章被收录于专栏:pangguomingpangguoming
运行总次数:0
代码可运行

在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,那该如何减少程序异常对用户体验的影响呢?其实方法很简单,对异常进行捕获,然后给予相应的处理即可。但实现的方式却有好多种,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try {
    ...
} catch (Exception e) {
    doSomeThing();
}

像这种标准的 try-catch 是可以解决问题,但如果让你在每个接口实现里面都 try-catch 一下,我想你应该是不太愿意的。那么下面来介绍下 SpringBoot 为我们提供的处理方式。

1. ErrorController 应用

首先,我们来模拟一下,出现异常的场景,方式比较简单,直接在正常的代码里面抛出一个异常即可。

在上面的示例中,调用接口时,出现了异常,但客户端却收到一个相对正常的响应,这是因为 SpringBoot 默认提供了一个 /error 的映射,该映射被注册为 Servlet 容器中的一个全局错误页面用来合理处理所有的异常情况。但示例中的响应报文不符合我们定义的数据规范,想要使其满足自己的数据规范,可以自己定义一个新的 ErrorController,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class FundaErrorController implements ErrorController {

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping
    @ResponseBody
    public Result doHandleError() {
        return new Result(ResultCode.WEAK_NET_WORK);
    }
}

当我们再次访问该接口的时候会返回:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  "code": -1,
  "msg": "网络异常,请稍后重试",
  "data": null
}

2. ExceptionHandler 应用

熟悉 SpringMVC 的人应该都知道 @ExceptionHandler 这个注解,在 SpringBoot 里面,我们同样可以使用它来做异常捕获。

2.1. 单一 Controller 异常处理

这种方式使用场景较少,但作为学习 @ExceptionHandler 入门示例还是非常不错的,直接在对应的 Controller 里面增加一个异常处理的方法,并使用 @ExceptionHandler 标识它即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ExceptionHandler(Exception.class)
public Result handleException() {
    return new Result(ResultCode.WEAK_NET_WORK);
}

客户端得到的效果与使用 ErrorController 完全一致,但对于服务端来说却不太一样,如果仔细观察这两种方式的日志输出的话,会发现使用 ErrorController 时,后台会打印出异常堆栈信息,而使用 @ExceptionHandler 却不会,这是因为这两种处理方式的流程存在着本质的差别。

  1. ErrorController: 调用 UserController 抛出异常时,自身没有做任何处理,所以会打印出堆栈信息,但这个异常会被 Servlet 容器捕捉到,Servlet 容器再将请求转发给注册好的异常处理映射 /error 做处理,客户端收到的实际是 ErrorController 的处理结果,而不是 UserController 的。
  2. ExceptionHandler: 异常的处理方法直接被定义在 UserController 里面,也就是说,在异常抛出的时候,UserController 会使用自己的方法去做异常处理,而不会抛出给 Servlet 容器,所以这个地方没有打印堆栈信息。

如果想要在后台添加堆栈信息的输出也非常简单,只需要将该异常作为一个参数传递给异常处理方法,然后在处理方法里面做相应的操作即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ExceptionHandler(Exception.class)
public Result handleException(Exception e) {
    e.printStackTrace();
    return new Result(ResultCode.WEAK_NET_WORK);
}

2.2. 父级 Controller 异常处理

项目的往往存在着多个 Controller,而它们在异常处理方面有存在着很多的共性,这样就不太适合在每一个 Controller 里面都编写一个对应的异常处理方法。可以将异常处理方法向上挪移到父类中,然后所有的 Controller 统一继承父类即可。

定义父类 BaseController:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class BaseController {

    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        e.printStackTrace();
        return new Result(ResultCode.WEAK_NET_WORK);
    }

}

UserController 通过继承 BaseController 完成异常处理:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RestController
@RequestMapping("/sys/user")
public class UserController extends BaseController {
    ...
}

2.3. Advice 异常处理

对于使用父级 Controller 完成异常处理也有着它自己的缺点,那就是代码耦合严重,一旦哪天忘记继承 BaseController,异常又会直达客户了。想要解除这种耦合关系,可以使用 @ControllerAdvice 来协助处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ControllerAdvice
@ResponseBody
public class ExceptionHandlerAdvice {

    @ExceptionHandler(Exception.class)
    public Result handleException(Exception e) {
        e.printStackTrace();
        return new Result(ResultCode.WEAK_NET_WORK);
    }

}

3. 多类别异常处理

实际的开发场景中,异常是区分很多类别的,不同类别的异常需要给用户不同的反馈。例如,在 SpringBoot实战 之 数据交互篇 中有使用到注解式参数校验,但校验不通过原因并没有以有效的方式告之给前端应用。下面我们通过上面提到的异常处理方式来完成这个功能:

首先,在 ResultCode 类中定义好 参数错误 的 code,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
PARAMETER_ERROR(10101, "参数错误")
  • 1

在 ExceptionHandlerAdvice 中添加对应的异常处理方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result handleIllegalParamException(MethodArgumentNotValidException e) {
    List<ObjectError> errors = e.getBindingResult().getAllErrors();
    String tips = "参数不合法";
    if (errors.size() > 0) {
        tips = errors.get(0).getDefaultMessage();
    }
    Result result = new Result(ResultCode.PARAMETER_ERROR);
    result.setMsg(tips);
    return result;
}

当应用程序抛出 MethodArgumentNotValidException 时,会精确匹配到该方法,在方法里面会获取到校验结果,并将所有校验错误中的第一条返回给前端应用。

这样的话,就可以在 ExceptionHandlerAdvice 里面添加各种各样的异常处理方法,以适合不同的应用场景。

项目的 github 地址:https://github.com/qchery/funda

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-02-07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
背景代码磁力小棍棍JS代码
好玩的JS特效,可以当做背景使用,代码在下面,也可以到示例网站复制源代码 示例网站:www.catcool.cn/gg 代码: <body> <script> ! function() { //封装方法,压缩之后减少文件大小 function get_attribute(node, attr, default_value) { return node.getAttribute(attr) || default_value; } //封装方法,压缩之后减少文件大小 function get_by_tagnam
叮当叮
2020/04/20
1.5K0
背景代码磁力小棍棍JS代码
【NexT主题美化】点击页面浮现24字核心价值观
在许多时候,我们希望用户点击页面时会有一定的反馈(如浮现字幕、放烟花)。这次,我们来实现一下如何使用户点击页面时,弹出24字核心价值观。
pai233
2022/01/12
5200
【NexT主题美化】点击页面浮现24字核心价值观
博客园富强民主文明和谐样式
最近很多人问我这个东西是怎么实现的。 那我就分享一下吧 :grin: <!--富强民主点击特效--> <script type="text/javascript"> /* 鼠标特效 */ var a_idx = 0; var b_idx = 0; /* 文字和颜色数组 */ var a = new Array("富强", "民主", "文明", "和谐", "自由", "平等", "公正" ,"法治", "爱国", "敬业", "诚信", "友善"); var b = new Array(
attack
2018/04/11
9120
博客园富强民主文明和谐样式
给网站添加鼠标点击特效富强、民主、和谐
(function() { var s = "_" + Math.random().toString(36).slice(2); document.write('<div style="" id="' + s + '"></div>'); (window.slotbydup = window.slotbydup || []).push({ id: "u4235867", container: s }); })();
爱游博客
2019/08/06
1.5K0
Markdown 拓展-Docsify / 博客园加特效
文字特效 <script type="text/javascript"> var a_idx = 0; jQuery(document).ready(function($) { $("body").click(function(e) { var a = new Array("❤学习","❤奥利给","❤干就完事","❤一giao我里giaogiao"); var $i = $("<span></span>").text(a[a_idx]); a_idx
acc8226
2022/05/17
3290
点击鼠标出现漂浮字体("自信", "自强", "坚持"...)效果实现
  前面我们谈到了漂浮磁力线/鼠标吸铁石特效你也可以实现,现在来聊聊点击鼠标出现漂浮字体("自信", "自强", "坚持"...)效果的实现,这两个小技巧的小心机都是吸引访客在页面的停留时间,感兴趣的朋友可以试试,这个特效只需要复制 JS 代码就可以。代码如下:
ytkah
2022/03/14
7880
点击页面弹出富强、民主、文明、和谐、自由、平等、公正、法治、爱国、敬业、诚信、友善社会主义核心价值观这类文字动画效果
一、文字动画效果预览 点击本页面任意位置即可!说明:此代码依赖jquery文件,一般网站都会有, 二、如何在自己网站上添加类似效果? 复制并粘贴下面的代码到页面任意位置 <!--富强--> <script type="text/javascript"> /* 鼠标特效 */ var a_idx = 0; jQuery(document).ready(function($) {      $("body").click(function(e) {          var a = new Array("
雾海梦曦
2022/11/14
7570
点击页面弹出富强、民主、文明、和谐、自由、平等、公正、法治、爱国、敬业、诚信、友善社会主义核心价值观这类文字动画效果
给typecho添加社会主义核心价值观24字特效,鼠标点击出现富强,民主,文明等等12组词
2014年2月12日,“富强、民主、文明、和谐、自由、平等、公正、法治、爱国、敬业、诚信、友善”的社会主义核心价值观基本内容公布。
小唐同学.
2022/02/17
1.3K0
WordPress主题添加鼠标点击特效
介绍几种WordPress主题添加“富强、民主、文明、和谐、”等鼠标点击特效方法以及代码使用。
小狐狸说事
2022/11/22
1.3K0
网站添加“富强·民主·爱国”鼠标点击特效美化
部署到自己的网站非常的简单,几乎是支持所有的站点,一般情况下只要将复制好的代码粘贴到</body>之前就行了。如果是WordPress网站直接添加到footer.php文件的</body>之前就OK了。代码中的字体以及属性均可以自定义设置,因为上面附上另种不同效果的代码,大家选一个喜欢的给自己的网站装饰下看看效果吧!如果添加后未生效请尝试清理CDN缓存或者浏览器缓存就可以了。
若梦
2022/04/01
5000
js代码实现鼠标点击爱心、爱国文字特效
添加目录wp-content/themes/ripro/parts diy-footer.php
keyi的猫
2022/03/30
5.9K0
js代码实现鼠标点击爱心、爱国文字特效
Typecho的一些修改记录
需要修改typecho的源代码,在typecho目录下的var/Widget/Abstract/Contents.php 文件中,搜索此内容被密码保护 找到对应行,在该行的开头添加两个斜杆,注释掉该行代码即可。
吴蛋蛋
2023/03/14
4360
Typecho的一些修改记录
一行代码给网站加上鼠标点击文字特效
常见问题:不生效~~~? 那么查看你的网站是否有引入jq文件,若没有添加一行引入。
Lcry
2022/11/29
5210
wordpresss加富强民主点击特效 Wordpress 博客 2 年前 桃李Taoli
添加以下代码到footer.php中 <script type="text/javascript"> /* 鼠标特效 */ var a_idx = 0; jQuery(document).ready(function($) { $("body").click(function(e) { var a = new Array("富强", "民主", "文明", "和谐", "自由", "平等", "公正" ,"法治", "爱国", "敬业", "诚信", "友善"); var
taoli
2022/09/30
3370
Handsome主题美化代码
原文地址:https://blog.ascv.cn/archives/554.html
傲绝
2023/03/08
1.3K0
Typecho主题Handsome修改记录---(持续更新)
usr/themes/handsome/component/footer.php删代码至如图所示
BinGo_Blog
2022/11/01
1.3K0
页面点击特效源码解析
这次给大家分享一个被广泛应用在个人网站中的骚骚的效果,就是鼠标左键点击出现小心心,来看下效果 :
石璞东
2020/04/21
1.3K0
小白如何在博客园上创建一个自己的超美化博客
我总想着一个人学了那么多东西,最后究竟有什么留了下来了?到现在回过头来一看,发现没有看到有什么时留下来的,保存在记忆中的知识也会逐渐的忘掉。所以,弄一个自己的博客,把学过的,学到的东西留下来,让自己看得到,也能让别人看得到。与这个世界的交互,从此刻开始吧!
西西嘛呦
2020/08/26
5.5K5
小白如何在博客园上创建一个自己的超美化博客
给网页添加鼠标点击特效。
这个特效、我开始想在自己的博客网页上弄一个玩玩,上百度搜的、开始没把关键字打对、导致找了大半天、心灰意冷之际把“富强、民主、和谐”等字样打上果断找到。其实网上是有许多教程,看到后也收集来了。其实就是一个JS、代码如下。把JS放在</body>标签前面就可以使用了。
白黎
2023/03/16
3K0
给网页添加鼠标点击特效。
鼠标点击出现爱心动效
起这么个标题,感觉瞬间回到了那个前端蛮荒的年代,各种滑动门特效。。。 还是在同一个博客上扒到的效果,地址在这 点我 $("html,body").click(function(e) { var gcd = new Array("♥", "♥", "♥"); var n = Math.floor(Math.random() * gcd.length); var $i = $("<b/>").text(gcd[n]); var x = e.pageX, y = e.pageY; $i.css({
上山打老虎了
2022/06/14
5550
推荐阅读
相关推荐
背景代码磁力小棍棍JS代码
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验