SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」
有天上飞的概念,就要有落地的实现
概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍
先赞后看,养成习惯
springboot 图文教程系列文章目录
- springboot图文教程1—springboot+mybatis 环境搭建
- springboot图文教程2—日志的使用「logback」「log4j」
- springboot图文教程3—「‘初恋’情结」集成jsp
- springboot图文教程4—springboot 实现文件上传下载
- springboot图文教程5—springboot 中使用aop
- springboot图文教程6—springboot中过滤器的使用
- springboot图文教程7—springboot拦截器的使用姿势这都有
- springboot图文教程8—springboot集成mbg「代码生成器」
- springboot图文教程9—springboot 导入导出 excel 「apache poi」
- springboot图文教程10—模板导出|百万数据excel导出|图片导出「easypoi」
- springboot图文教程11—从此不写mapper文件「springboot集成mybatisplus」
- springboot图文教程12—springdata jpa的基本使用
- springboot图文教程13—springboot+idea实现代码热部署
- springboot图文教程14—阿里开源easyexcel「为百万数据读写设计」
前言
本文教程示例代码见码云仓库:https://gitee.com/bingqilinpeishenme/boot-demo
异常处理在java中是一种很常规的操作,在代码中我们常用的方法是try catch或者上抛异常。
但是,如果controller发生异常了怎么办?业务层的异常可以在controller捕获,controller抛出的异常怎么捕获?springmvc的异常怎么捕获?
这个时候常见的操作有两种:
- 跳转错误页面,例如:找不到路径的时候跳转404,代码报错的时候跳转500等
- 响应统一的报错信息,使用result对象(自定义的实体类)封装错误码,错误描述信息响应【分布式服务调用的时候推荐使用】
今天我们就简单的来讲解一下springboot中如何进行异常处理,跳转404或者封装错误信息响应。
跳转错误页面
springboot 错误页面的默认配置
在springboot中 error page错误页面是有默认配置的,默认配置是这样
如果在static目录中存在error文件夹,并且文件夹中存在400.html,或者500.html,出现对应的响应状态的时候(404和500的使用),会跳转到对应的页面
如果你使用的是webapp目录,也是一样的,只要在webapp目录中存在400.jsp页面(html也一样),出现对应的响应状态的时候(404和500的使用),会跳转到对应的页面
以上是默认配置,只要是springboot的项目都会生效,接下来我们来测试一下
在static目录下创建error文件夹,400.html以及500.html
写一个会报错的controller方法 test500
启动项目分别访问一个不存在的路径【测试】和访问会报错的controller方法,效果如下
自定义错误页面的配置
以上是springboot关于错误页面的默认配置,但是很多时候我们的需求比springboot的默认配置要复杂很多,例如:404页面不想放在error文件夹下,500错误的时候也不想跳转页面,而是响应给页面一个json的数据等。
这个时候需要做的就是修改springboot的默认配置了。
实现的目标:
- 404的时候跳转到static下的404页面
- 500的时候响应页面一句话:“后台错误 请联系管理员”
第一步:创建一个能够响应 “后台错误 请联系管理员” 这句话的controller方法,将404页面放在static下面【如果是webapp也一样】
第二步:创建错误页面的配置类,修改默认的配置
/** * 错误页面配置 * * 继承错误页面注册器 errorpageregistrar */ @configuration public class errorconfig implements errorpageregistrar { @override public void registererrorpages(errorpageregistry registry) { /** * 配置错误页面 * * errorpage 有两个参数 * 参数1 响应状态码 not_found 404 internal_server_error 500 * 参数2 出现响应状态码的时候的跳转路径 可以自定义跳转路径 */ errorpage error404 = new errorpage(httpstatus.not_found, "/404.html"); errorpage error500 = new errorpage(httpstatus.internal_server_error, "/testdata"); /** * 将errorpage 注册到注册器中 */ registry.adderrorpages(error404,error500); } }
第三步:启动项目,可以看到如下效果
访问不存在的路径,跳转404页面
访问 http://localhost:8802/test500 效果如下:
以上就是跳转404和统一响应数据的操作,但是还有问题,什么问题呢?
以上的操作实际上没有针对异常进行捕获,而是根据响应的状态码进行不同的处理的,那么如果才能针对不同的异常进行捕获呢?这就要用到全局异常捕获了。
全局异常捕获
还记得文章开头说过的第二个场景吗?使用result对象(自定义的实体类)统一封装异常状态码,异常信息,进行返回。通过全局异常捕获就可以实现。
测试的要求是:
- 捕获自定义异常,封装result对象以json的格式响应
- 捕获自定义异常,跳转到错误页面
1.自定义异常
在应用开发过程中,除系统自身的异常外,不同业务场景中用到的异常也不一样,很多时候需要自定义异常,所以我们自定义两个异常,分别是:
- errorreturnresultexception 如果出现这个异常,就返回统一result对象
- errorreturnpageexception 如果出现这个异常,就跳转错误页面
errorreturnresultexception
package com.lu.bootexception.exception; public class errorreturnresultexception extends runtimeexception { /** * 错误码 */ private int code; public errorreturnresultexception() { } public errorreturnresultexception(string message) { super(message); } public errorreturnresultexception(string message, int code) { super(message); this.code = code; } public int getcode() { return code; } public void setcode(int code) { this.code = code; } }
errorreturnpageexception
package com.lu.bootexception.exception; public class errorreturnpageexception extends runtimeexception { /** * 错误码 */ private int code; public errorreturnpageexception() { } public errorreturnpageexception(string message, int code) { super(message); this.code = code; } public errorreturnpageexception(string message) { super(message); } public int getcode() { return code; } public void setcode(int code) { this.code = code; } }
2.自定义响应实体
定义返回的异常信息的格式,这样异常信息风格更为统一
package com.lu.bootexception.exception; import lombok.data; @data @noargsconstructor @allargsconstructor public class result { private int code; private string message; }
3.全局异常捕获实现
利用spring的api定义一个全局异常处理的类,代码和注释如下:
package com.lu.bootexception.exception; import org.springframework.web.bind.annotation.controlleradvice; import org.springframework.web.bind.annotation.exceptionhandler; import org.springframework.web.bind.annotation.responsebody; /** * @controlleradvice 增强controller的注解 可以实现全局异常捕获 */ @controlleradvice public class globalexceptionhandler { /** * @exceptionhandler 指明要捕获那个异常 * 不加@responsebody 会使用视图解析器跳转页面 * 形参处是exception 简单来说就是会把捕获到的异常通过形参传入方法中 */ @exceptionhandler(errorreturnpageexception.class) public string errorreturnpageexception(exception e){ // 打印错误信息 system.out.println(e.getmessage()); // 跳转500页面 return "forward:/500.html"; } /** * 捕获 errorreturnresultexception 异常 * 通过 @responsebody 注解响应数据 会以json的格式响应 */ @exceptionhandler(errorreturnresultexception.class) @responsebody public result errorreturnresultexception(final exception e) { errorreturnresultexception exception = (errorreturnresultexception) e; /** * result 中可以写入自定义的异常状态码 */ return new result(5001, exception.getmessage()); } /** * 捕获 runtimeexception 异常 */ @exceptionhandler(runtimeexception.class) @responsebody public result runtimeexceptionhandler(final exception e) { runtimeexception exception = (runtimeexception) e; /** * result 中可以写入自定义的异常状态码 */ return new result(4004, exception.getmessage()); } }
代码中用到的注解
- @controlleradvice 捕获抛出的异常,如果添加
@responsebody
返回信息则为json
格式。- @restcontrolleradvice 相当于
@controlleradvice
与@responsebody
的结合体。- @exceptionhandler 指明要捕获那个异常
4.写两个测试方法 测试全局异常捕获的效果
访问 http://localhost:8802/testreturnpage 会跳转错误页面
访问 http://localhost:8802/testreturnresult 会返回统一的json数据
总结
恭喜你完成了本章的学习,为你鼓掌!如果本文对你有帮助,请帮忙点赞,评论,转发,这对作者很重要,谢谢。
让我们再次回顾本文的学习目标
- 掌握springboot中异常处理的基本使用
要掌握springboot更多的用法,请持续关注本系列教程。
求关注,求点赞,求转发
欢迎关注本人公众号:鹿老师的java笔记,将在长期更新java技术图文教程和视频教程,java学习经验,java面试经验以及java实战开发经验。