欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-16 09:42:03
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 1. "SpringBoot图文教程1—SpringBoot+Mybatis 环境搭建" 2. "SpringBoot图文教程2—日志的使 ......

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

有天上飞的概念,就要有落地的实现

  • 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍

  • 先赞后看,养成习惯

springboot 图文教程系列文章目录

  1. springboot图文教程1—springboot+mybatis 环境搭建
  2. springboot图文教程2—日志的使用「logback」「log4j」
  3. springboot图文教程3—「‘初恋’情结」集成jsp
  4. springboot图文教程4—springboot 实现文件上传下载
  5. springboot图文教程5—springboot 中使用aop
  6. springboot图文教程6—springboot中过滤器的使用
  7. springboot图文教程7—springboot拦截器的使用姿势这都有
  8. springboot图文教程8—springboot集成mbg「代码生成器」
  9. springboot图文教程9—springboot 导入导出 excel 「apache poi」
  10. springboot图文教程10—模板导出|百万数据excel导出|图片导出「easypoi」
  11. springboot图文教程11—从此不写mapper文件「springboot集成mybatisplus」
  12. springboot图文教程12—springdata jpa的基本使用
  13. springboot图文教程13—springboot+idea实现代码热部署
  14. springboot图文教程14—阿里开源easyexcel「为百万数据读写设计」

前言

本文教程示例代码见码云仓库: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的使用),会跳转到对应的页面
    SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

  • 如果你使用的是webapp目录,也是一样的,只要在webapp目录中存在400.jsp页面(html也一样),出现对应的响应状态的时候(404和500的使用),会跳转到对应的页面
    SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

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

  1. 在static目录下创建error文件夹,400.html以及500.html
    SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

  2. 写一个会报错的controller方法 test500
    SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

  3. 启动项目分别访问一个不存在的路径【测试】和访问会报错的controller方法,效果如下
    SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

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

自定义错误页面的配置

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

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

实现的目标:

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

第一步:创建一个能够响应 “后台错误 请联系管理员” 这句话的controller方法,将404页面放在static下面【如果是webapp也一样】
SpringBoot图文教程15—项目异常怎么办?「跳转404错误页面」「全局异常捕获」

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

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

/**
 * 错误页面配置
 *
 * 继承错误页面注册器 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页面

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

访问 http://localhost:8802/test500 效果如下:

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

以上就是跳转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.写两个测试方法 测试全局异常捕获的效果

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

访问 http://localhost:8802/testreturnpage 会跳转错误页面

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

访问 http://localhost:8802/testreturnresult 会返回统一的json数据

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

总结

恭喜你完成了本章的学习,为你鼓掌!如果本文对你有帮助,请帮忙点赞,评论,转发,这对作者很重要,谢谢。

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

让我们再次回顾本文的学习目标

  • 掌握springboot中异常处理的基本使用

要掌握springboot更多的用法,请持续关注本系列教程。

求关注,求点赞,求转发

欢迎关注本人公众号:鹿老师的java笔记,将在长期更新java技术图文教程和视频教程,java学习经验,java面试经验以及java实战开发经验。