Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

作者头像
鹿老师的Java笔记
发布于 2020-03-30 08:19:49
发布于 2020-03-30 08:19:49
1.5K00
代码可运行
举报
运行总次数:0
代码可运行
前言

本文教程示例代码见码云仓库:https://gitee.com/bingqilinpeishenme/boot-demo

异常处理在Java中是一种很常规的操作,在代码中我们常用的方法是try catch或者上抛异常。

但是,如果Controller发生异常了怎么办?业务层的异常可以在Controller捕获,Controller抛出的异常怎么捕获?SpringMvc的异常怎么捕获?

这个时候常见的操作有两种:

  1. 跳转错误页面,例如:找不到路径的时候跳转404,代码报错的时候跳转500等
  2. 响应统一的报错信息,使用Result对象(自定义的实体类)封装错误码,错误描述信息响应【分布式服务调用的时候推荐使用】

今天我们就简单的来讲解一下SpringBoot中如何进行异常处理,跳转404或者封装错误信息响应。

跳转错误页面

SpringBoot 错误页面的默认配置

在SpringBoot中 error page错误页面是有默认配置的,默认配置是这样

  • 如果在static目录中存在error文件夹,并且文件夹中存在400.html,或者500.html,出现对应的响应状态的时候(404和500的使用),会跳转到对应的页面
  • 如果你使用的是webapp目录,也是一样的,只要在webapp目录中存在400.jsp页面(html也一样),出现对应的响应状态的时候(404和500的使用),会跳转到对应的页面

以上是默认配置,只要是SpringBoot的项目都会生效,接下来我们来测试一下

  1. 在static目录下创建error文件夹,400.html以及500.html
  1. 写一个会报错的Controller方法 test500
  1. 启动项目分别访问一个不存在的路径【测试】和访问会报错的Controller方法,效果如下

自定义错误页面的配置

以上是SpringBoot关于错误页面的默认配置,但是很多时候我们的需求比SpringBoot的默认配置要复杂很多,例如:404页面不想放在error文件夹下,500错误的时候也不想跳转页面,而是响应给页面一个json的数据等。

这个时候需要做的就是修改SpringBoot的默认配置了。

实现的目标:

  • 404的时候跳转到static下的404页面
  • 500的时候响应页面一句话:“后台错误 请联系管理员”

第一步:创建一个能够响应 “后台错误 请联系管理员” 这句话的Controller方法,将404页面放在static下面【如果是webapp也一样】

第二步:创建错误页面的配置类,修改默认的配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 错误页面配置
 *
 * 继承错误页面注册器 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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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.自定义响应实体

定义返回的异常信息的格式,这样异常信息风格更为统一

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.lu.bootexception.exception;

import lombok.Data;


@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private int code;
    private String message;
}

3.全局异常捕获实现

利用Spring的API定义一个全局异常处理的类,代码和注释如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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更多的用法,请持续关注本系列教程。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鹿小洋的Java笔记 微信公众号,前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
spring-boot-route(四)全局异常处理
在开发中,我们经常会使用try/catch块来捕获异常进行处理,如果有些代码中忘记捕获异常或者不可见的一些异常出现,就会响应给前端一些不友好的提示,这时候我们可以使用全局异常处理。这样就不用在代码中写那些烦人的try/catch块了,代码的可读性也会提高。
Java旅途
2020/10/21
6210
看看别人家 SpringBoot 的全局异常处理,多么优雅....
> 公众号:[Java小咖秀](https://t.1yb.co/jwkk),网站:[javaxks.com](https://www.javaxks.com)
Java小咖秀
2021/04/18
4560
看看别人家 SpringBoot 的全局异常处理,多么优雅....
Spring Boot简明教程--全局异常处理
为了统一开发过程中的异常处理方式和返回值,需要为项目制定统一的全局异常处理。在SpringBoot中全局异常处理通过@ControllerAdvice注解以及 @ExceptionHandler注解来实现,前者是用来开启全局的异常捕获,后者则是说明捕获哪些异常,对哪些异常进行处理。
听城
2021/01/29
5970
SpringBoot 定义优雅全局统一 Restful API 响应和统一异常处理,太优雅了!
假如你作为项目组长,为 Spring Boot 项目设计一个规范的统一的RESTfulAPI 响应框架。
码哥字节
2024/11/23
2960
SpringBoot 定义优雅全局统一 Restful API 响应和统一异常处理,太优雅了!
SpringBoot错误信息处理机制及原理
ErrorMvcAutoConfiguration这个类存放了所有关于错误信息的自动配置。
石的三次方
2021/01/06
9250
Spring Boot统一异常处理
先定义接口返回数据结构,code为0表示操作成功,非0表示异常。其中data只有在处理成功才会返回,其他情况不会返回,或者那些不需要返回数据的接口(更新、删除…)
用户7353950
2022/06/23
4600
Spring Boot统一异常处理
springboot 统一异常处理(包含统一数据校验)
(1)只要没有成功,不管什么原因,前端界面给出提示:服务端错误/异常。哪怕是数据校验不过,也这样提示(嗯,反正先把锅甩出去再说,具体什么原因我才不在乎呢,老子就是这么聪明);
java架构师
2019/04/09
1.1K0
springboot 统一异常处理(包含统一数据校验)
SpringBoot中如何实现接口的统一返回和异常的统一捕获
在开发公司接口时,发现Controller层的接口返回都需要用一个Result包裹,如下图所示:
Lvshen
2022/05/05
1.3K0
SpringBoot中如何实现接口的统一返回和异常的统一捕获
SpringBoot全局异常处理
估计大家都会了的^_^,本文代码为主,在做Web应用的时候,请求处理过程中发生错误是非常常见的情况,那我们如何才能统一且友好地返回系统异常给前台呢。
用户3467126
2019/08/16
8100
SpringBoot全局异常处理
SpringBoot处理全局统一异常
0x01:使用@ControllerAdvice和@ExceptionHandler注解
BUG弄潮儿
2020/06/15
1.1K0
springboot搞定全局自定义异常
大家好,我是架构君,一个会写代码吟诗的架构师。今天说一说springboot搞定全局自定义异常,希望能够帮助大家进步!!!
Java架构师必看
2021/11/30
4360
重学SpringBoot系列之统一全局异常处理
答:因为用户不认识ConnectionTimeOutException类似这种异常是什么东西,但是转换为自定义异常就要求程序员对运行时异常进行一个翻译,比如:自定义异常里面应该有message字段,后端程序员应该明确的在message字段里面用面向用户的友好语言,说明服务端发生了什么。
大忽悠爱学习
2021/12/07
1K0
重学SpringBoot系列之统一全局异常处理
一起来学SpringBoot | 第十八篇:轻松搞定全局异常
实际项目开发中,程序往往会发生各式各样的异常情况,特别是身为服务端开发人员的我们,总是不停的编写接口提供给前端调用,分工协作的情况下,避免不了异常的发生,如果直接将错误的信息直接暴露给用户,这样的体验可想而知,且对黑客而言,详细异常信息往往会提供非常大的帮助...
battcn
2018/08/03
6500
一起来学SpringBoot | 第十八篇:轻松搞定全局异常
SpringBoot系列(九)统一异常处理与统一结果返回
 日常开发过程中,难免有的程序会因为某些原因抛出异常,而这些异常一般都是利用try ,catch的方式处理异常或者throw,throws的方式抛出异常不管。这种方法对于程序员来说处理也比较麻烦,对客户来说也不太友好,所以我们希望既能方便程序员编写代码,不用过多的自己去处理各种异常编写重复的代码又能提升用户的体验,这时候全局异常处理就显得很重要也很便捷了,是一种不错的选择。
全栈学习笔记
2022/03/31
2.4K0
SpringBoot系列(九)统一异常处理与统一结果返回
SpringBoot---错误处理机制
一但系统出现4xx或者5xx之类的错误;ErrorPageCustomizer就会生效(定制错误的响应规则);就会来到/error
大忽悠爱学习
2021/11/15
4730
SpringBoot-08-之统一化json输出与自定义异常捕获
为及时了解异常,以及避免返回的json格式不统,将每次请求的结果都返还一样的形式。 此处统一为:{"code":响应代号码,"msg":信息,"data":数据} 具体效果如下: result-
张风捷特烈
2018/09/26
1.2K0
Springboot全局异常处理
1、全局异常处理,指的是对于程序中产生的Exception进行的处理。产生了异常之后,可以统一跳转到一个页面进行错误提示,也可以通过Restful形式返回错误信息。
别先生
2020/11/24
5070
Springboot全局异常处理
SpringBoot系列教程web篇之全局异常处理
当我们的后端应用出现异常时,通常会将异常状况包装之后再返回给调用方或者前端,在实际的项目中,不可能对每一个地方都做好异常处理,再优雅的代码也可能抛出异常,那么在 Spring 项目中,可以怎样优雅的处
一灰灰blog
2019/10/14
8680
SpringBoot系列教程web篇之全局异常处理
Spring | 如何在项目中优雅的处理异常 - 全局异常处理以及自定义异常处理
在快速迭代和持续交付的今天,软件的健壮性、可靠性和用户体验已经成为区别成功与否的关键因素。特别是在Spring框架中,由于其广泛的应用和丰富的功能,如何优雅地处理异常就显得尤为重要。本文旨在探讨在Spring中如何更加高效、准确和优雅地处理异常,帮助开发者更好地构建和维护Spring应用。
kfaino
2023/09/26
3.9K0
Spring | 如何在项目中优雅的处理异常 - 全局异常处理以及自定义异常处理
使用枚举简单封装一个优雅的 Spring Boot 全局异常处理!
通过这篇文章,可以搞懂如何在 Spring Boot 中进行异常处理。但是,光是会用了还不行,我们还要思考如何把异常处理这部分的代码写的稍微优雅一点。下面我会以我在工作中学到的一点实际项目中异常处理的方式,来说说我觉得稍微优雅点的异常处理解决方案。
Guide哥
2020/05/07
1.5K0
推荐阅读
相关推荐
spring-boot-route(四)全局异常处理
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文