美文网首页Bug记录
SpringBoot自定义项目异常----「跳转404错误页面」

SpringBoot自定义项目异常----「跳转404错误页面」

作者: 花伤情犹在 | 来源:发表于2021-10-10 13:29 被阅读0次

    异常处理在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的使用),会跳转到对应的页面


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


      image.png

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

    1. 在static目录下创建error文件夹,400.html以及500.html


      image.png
    2. 写一个会报错的Controller方法 test500


      image.png
    3. 启动项目分别访问一个不存在的路径【测试】和访问会报错的Controller方法,效果如下


      image.png
      image.png

    自定义错误页面的配置

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

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

    实现的目标:

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

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

    image.png image.png

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

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

    image.png

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

    image.png

    以上的操作实际上没有针对异常进行捕获,而是根据响应的状态码进行不同的处理的,那么如果才能针对不同的异常进行捕获呢?这就要用到全局异常捕获了。

    全局异常捕获

    还记得文章开头说过的第二个场景吗?使用Result对象(自定义的实体类)统一封装异常状态码,异常信息,进行返回。通过全局异常捕获就可以实现。

    测试的要求是:

    • 捕获自定义异常,封装Result对象以json的格式响应
    • 捕获自定义异常,跳转到错误页面

    自定义异常

    在应用开发过程中,除系统自身的异常外,不同业务场景中用到的异常也不一样,很多时候需要自定义异常,所以我们自定义两个异常,分别是:

    • ErrorReturnResultException 如果出现这个异常,就返回统一Result对象
    • ErrorReturnPageException 如果出现这个异常,就跳转错误页面

    ErrorReturnResultException

    Exception(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 指明要捕获那个异常

    写两个测试方法 测试全局异常捕获的效果

    image.png
    访问 http://localhost:8802/testReturnPage 会跳转错误页面
    image.png
    访问 http://localhost:8802/testReturnResult 会返回统一的json数据
    image.png

    相关文章

      网友评论

        本文标题:SpringBoot自定义项目异常----「跳转404错误页面」

        本文链接:https://www.haomeiwen.com/subject/ecsholtx.html