Spring Boot 全局异常处理

本贴最后更新于 2976 天前,其中的信息可能已经时移世改

我们在做 Web 应用的时候,请求处理过程中发生错误是非常常见的情况。Spring Boot 提供了一个默认的映射:/error,当处理中抛出异常之后,会转到该请求中处理,并且该请求有一个全局的错误页面用来展示异常内容。

选择一个之前实现过的 Web 应用为基础,启动该应用,访问一个不存在的 URL,或是修改处理内容,直接抛出异常,如:

@RequestMapping("/hello") public String hello() throws Exception { throw new Exception("发生错误"); }

此时,报错页面,该页面就是 Spring Boot 提供的默认 error 映射页面。

统一异常处理

虽然,Spring Boot 中实现了默认的 error 映射,但是在实际应用中,上面你的错误页面对用户来说并不够友好,我们通常需要去实现我们自己的异常提示。

下面我们以之前的 Web 应用例子为基础,进行统一异常处理的改造。

创建全局异常处理类:通过使用 @ControllerAdvice 定义统一的异常处理类,而不是在每个 Controller 中逐个定义。@ExceptionHandler 用来定义函数针对的异常类型,最后将 Exception 对象和请求 URL 映射到 error.html 中

@ControllerAdvice class GlobalExceptionHandler { public static final String DEFAULT_ERROR_VIEW = "error"; @ExceptionHandler(value = Exception.class) public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { ModelAndView mav = new ModelAndView(); mav.addObject("exception", e); mav.addObject("url", req.getRequestURL()); mav.setViewName(DEFAULT_ERROR_VIEW); return mav; } }

实现 error.html 页面展示:在 templates 目录下创建 error.html,将请求的 URL 和 Exception 对象的 message 输出。

<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8" /> <title>统一异常处理</title> </head> <body> <h1>Error Handler</h1> <div th:text="${url}"></div> <div th:text="${exception.message}"></div> </body> </html>

启动该应用,访问:http://localhost:8080/hello,可以看到如下错误提示页面。

ErrorHandler
http://localhost:8080/hello
发生错误

通过实现上述内容之后,我们只需要在 Controller 中抛出 Exception,当然我们可能会有多种不同的 Exception。然后在 @ControllerAdvice 类中,根据抛出的具体 Exception 类型匹配 @ExceptionHandler 中配置的异常类型来匹配错误映射和处理。

返回 JSON 格式

在上述例子中,通过 @ControllerAdvice 统一定义不同 Exception 映射到不同错误处理页面。而当我们要实现 RESTful API 时,返回的错误是 JSON 格式的数据,而不是 HTML 页面,这时候我们也能轻松支持。

本质上,只需在 @ExceptionHandler 之后加入 @ResponseBody,就能让处理函数 return 的内容转换为 JSON 格式。

下面以一个具体示例来实现返回 JSON 格式的异常处理。

创建统一的 JSON 返回对象,code:消息类型,message:消息内容,url:请求的 url,data:请求返回的数据

public class ErrorInfo<T> { public static final Integer OK = 0; public static final Integer ERROR = 100; private Integer code; private String message; private String url; private T data; // 省略getter和setter }

创建一个自定义异常,用来实验捕获该异常,并返回 json

public class MyException extends Exception { public MyException(String message) { super(message); } }

Controller 中增加 json 映射,抛出 MyException 异常

@Controller public class HelloController { @RequestMapping("/json") public String json() throws MyException { throw new MyException("发生错误2"); } }

为 MyException 异常创建对应的处理

@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = MyException.class) @ResponseBody public ErrorInfo<String> jsonErrorHandler(HttpServletRequest req, MyException e) throws Exception { ErrorInfo<String> r = new ErrorInfo<>(); r.setMessage(e.getMessage()); r.setCode(ErrorInfo.ERROR); r.setData("Some Data"); r.setUrl(req.getRequestURL().toString()); return r; } }

启动应用,访问:http://localhost:8080/json,可以得到如下返回内容:

{ code: 100, data: "Some Data", message: "发生错误2", url: "http://localhost:8080/json" }
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    947 引用 • 1460 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 735 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 85 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    43 引用 • 44 回帖 • 1 关注
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 314 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 351 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    10113 引用 • 45931 回帖 • 64 关注
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 37 关注
  • 印象笔记
    3 引用 • 16 回帖 • 2 关注
  • uTools

    uTools 是一个极简、插件化、跨平台的现代桌面软件。通过自由选配丰富的插件,打造你得心应手的工具集合。

    7 引用 • 28 回帖
  • AWS
    11 引用 • 28 回帖 • 8 关注
  • Log4j

    Log4j 是 Apache 开源的一款使用广泛的 Java 日志组件。

    20 引用 • 18 回帖 • 35 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    32 引用 • 108 回帖 • 1 关注
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    6 引用 • 143 回帖
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 248 回帖
  • RemNote
    2 引用 • 16 回帖 • 26 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    20 引用 • 37 回帖 • 572 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖
  • Linux

    Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 Unix 的多用户、多任务、支持多线程和多 CPU 的操作系统。它能运行主要的 Unix 工具软件、应用程序和网络协议,并支持 32 位和 64 位硬件。Linux 继承了 Unix 以网络为核心的设计思想,是一个性能稳定的多用户网络操作系统。

    955 引用 • 944 回帖
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    268 引用 • 666 回帖 • 3 关注
  • 小薇

    小薇是一个用 Java 写的 QQ 聊天机器人 Web 服务,可以用于社群互动。

    由于 Smart QQ 从 2019 年 1 月 1 日起停止服务,所以该项目也已经停止维护了!

    35 引用 • 468 回帖 • 764 关注
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 2 关注
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 681 关注
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    6 引用 • 26 回帖 • 546 关注
  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 233 回帖
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    115 引用 • 319 回帖
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖
  • 倾城之链
    23 引用 • 66 回帖 • 166 关注