有天上飞的概念,就要有落地的实现html
概念十遍不如代码一遍,朋友,但愿你把文中全部的代码案例都敲一遍git
先赞后看,养成习惯web
SpringBoot 图文教程系列文章目录面试
本文教程示例代码见码云仓库:https://gitee.com/bingqilinpeishenme/boot-demospring
异常处理在Java中是一种很常规的操做,在代码中咱们经常使用的方法是try catch或者上抛异常。json
可是,若是Controller发生异常了怎么办?业务层的异常能够在Controller捕获,Controller抛出的异常怎么捕获?SpringMvc的异常怎么捕获?springboot
这个时候常见的操做有两种:app
今天咱们就简单的来说解一下SpringBoot中如何进行异常处理,跳转404或者封装错误信息响应。webapp
在SpringBoot中 error page错误页面是有默认配置的,默认配置是这样jsp
若是在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的格式响应
- 捕获自定义异常,跳转到错误页面
在应用开发过程当中,除系统自身的异常外,不一样业务场景中用到的异常也不同,不少时候须要自定义异常,因此咱们自定义两个异常,分别是:
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; } }
定义返回的异常信息的格式,这样异常信息风格更为统一
package com.lu.bootexception.exception; import lombok.Data; @Data @NoArgsConstructor @AllArgsConstructor public class Result { private int code; private String message; }
利用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 指明要捕获那个异常
访问 http://localhost:8802/testReturnPage 会跳转错误页面
访问 http://localhost:8802/testReturnResult 会返回统一的json数据
恭喜你完成了本章的学习,为你鼓掌!若是本文对你有帮助,请帮忙点赞,评论,转发,这对做者很重要,谢谢。
让咱们再次回顾本文的学习目标
- 掌握SpringBoot中异常处理的基本使用
要掌握SpringBoot更多的用法,请持续关注本系列教程。
欢迎关注本人公众号:鹿老师的Java笔记,将在长期更新Java技术图文教程和视频教程,Java学习经验,Java面试经验以及Java实战开发经验。