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实战开发经验。
SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」的更多相关文章
- SpringBoot图文教程17—上手就会 RestTemplate 使用指南「Get Post」「设置请求头」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1-Spr ...
- 🔥SpringBoot图文教程2—日志的使用「logback」「log4j」
有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...
- SpringBoot图文教程3—「‘初恋’情结」集成Jsp
有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 文章结尾配套自测面试题,学完技术自我测试更扎实 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例 ...
- SpringBoot图文教程8 — SpringBoot集成MBG「代码生成器」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- SpringBoot图文教程9—SpringBoot 导入导出 Excel 「Apache Poi」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- SpringBoot图文教程10—模板导出|百万数据Excel导出|图片导出「easypoi」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- SpringBoot图文教程11—从此不写mapper文件「SpringBoot集成MybatisPlus」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- SpringBoot图文教程「概念+案例 思维导图」「基础篇上」
有天上飞的概念,就要有落地的实现 概念+代码实现是本文的特点,教程将涵盖完整的图文教程,代码案例 每个知识点配套自测面试题,学完技术自我测试 本文初学向,所以希望文中所有的代码案例都能敲一遍 大哥大姐 ...
- SpringBoot图文教程14—SpringBoot集成EasyExcel「上」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
随机推荐
- BigDecimal进行精确运算
public class Test_1 { public static void main(String[] args) { System.out.println(0.06+0.01); System ...
- HTML的img标签:alt属性和title属性
当浏览器卖主扭曲了标准并且自顾自的不按规则去做一些事,他们可能会造成一些问题,或者至少产生了混淆.例子之一就是一些浏览器处理alt属性(一般会被错误的称作alt标签)的方式,比如拥有大量用户的Wind ...
- 吴裕雄--天生自然Android开发学习:Android studio 3.5安装详解
3. 建立AVD(安卓虚拟设备) 点击右上角AVD Manager图标,单击按钮Create Virtual Device,选择Nexus 5X,下一步,选择版本9.0,Download,然后Next ...
- 4k高分屏下,chm帮助文档,api文档打开后字体过小的解决
如图所示: 4k分辨率下,chm文件的正文部分的字体过小,这是这些网页可能使用了CSS维持字体dpi, 在普通分辨率下,可以显示正常,但在高分屏下就会显示得过小,这时我们就需要调整显示网页 的显示效果 ...
- SpringMVC学习笔记五:HandlerExceptionResolver异常处理
继承HandlerExceptionResolver自定义异常处理器 控制器ExceptionController.java package com.orange.controller; import ...
- php--小数点问题
1.用round去小数点后两位时,有时候会出现很长的小数解决方法 sprintf("%.2f",round($total_fee,2)); 使用sprintf再截取一遍.出现变态小 ...
- 前端js代码以备不时之需
//获取id元素信息let getId = (args) => { return document.getElementById(args);} //获取类名元素let getClassName ...
- Java Design Patterns(2)
1.Factory Design pattern 工厂设计模式的优点 (1)工厂设计模式提供了接口而不是实现的代码方法. (2)工厂模式从客户端代码中删除实际实现类的实例化.工厂模式使我们的代码更健壮 ...
- SWUST OJ 东6宿舍灵异事件(0322)
东6宿舍灵异事件(0322) Time limit(ms): 1000 Memory limit(kb): 65535 Submission: 88 Accepted: 31 Descriptio ...
- 吴裕雄--天生自然 Tensorflow卷积神经网络:花朵图片识别
import os import numpy as np import matplotlib.pyplot as plt from PIL import Image, ImageChops from ...