• 10、SpringBoot之异常处理


    第一种:自定义错误页面

    • SpringBoot默认的处理异常的机制:SpringBoot默认的已经提供了一套处理异常的机制。
    • 一旦程序中出现了异常SpringBoot会向/error的url发送请求。
    • SpringBoot中提供了一个名为BasicErrorController来处理/error请求,然后跳转到默认显示异常的页面来展示异常信息。

    由于没有找到/error映射的文件,所以将错误返回到springboot的页面将异常信息进行输出

    Whitelabel Error Page
    This application has no explicit mapping for /error, so you are seeing this as a fallback.
    Thu Apr 23 23:29:38 CST 2020
    There was an unexpected error (type=Internal Server Error, status=500).
    No message available
    
    如果需要将所有异常统一跳转到自定义的错误页面,需要在**src/main/resources/templates** 目录下创建**error.html**页面。注意:页面必须叫**error**
    

    当有一个命名为error的错误页面时,出现异常则直接跳到该页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        出现错误异常
    </body>
    </html>
    

    缺点:当捕获到不同的异常想要跳转至不同页面是,自定义错误页面没办法实现;

    第二种:通过@ExceptionHandler注解处理异常

    • 修改Controller
    • 创建页面

    @ExceptionHandler注解可以做到根据不同异常类型,来跳转到不同的页面进行异常信息的显示

    我们需要在能够产生异常的方法所在的controller当中再添加一个处理异常的方法

    @Controller
    public class UsersController {
        /**
         * 定义一个会报出空指针异常的方法
         * @return
         */
        @RequestMapping("showInfo")
        public String showInfo(){
            String str = null;
            str.length();
            return "ok";
        }
    
    
        /**
         * 该方法会处理当前这个controller出现的空指针异常
         * @param e
         * @return
         */
        @ExceptionHandler(value = {java.lang.NullPointerException.class})
        public ModelAndView nullpointExceptionHandler(Exception e){
    //        e对象会接收放错传入的异常对象
            ModelAndView mv = new ModelAndView();
            mv.addObject("err", e);
            mv.setViewName("error1");
            return mv;
        }
    }
    

    error1页面

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        出错了。。。
        <span th:text="${err}"></span>
    </body>
    </html>
    

    缺点:单用一个@ExceptionHandler注解只能作用他当前的controller进行异常处理,如果其他controller也出现同样的异常是不会进行处理的,复用性差,这个时候需要@ControllerAdvice结合使用,使异常处理方法可以全局使用。

    第三种:通过@ControllerAdvice与@ExceptionHandler注解处理异常

    • 创建全局异常处理类

    Controller

    @Controller
    public class UsersController {
        /**
         * 定义一个会报出空指针异常的方法
         * @return
         */
        @RequestMapping("showInfo")
        public String showInfo(){
            String str = null;
            str.length();
            return "ok";
        }
        /**
         * 定义一个会报出算术异常的方法
         * @return
         */
        @RequestMapping("showInfo2")
        public String showInfo2(){
            int i = 10/0;
            return "ok";
        }
    }
    

    全局异常处理类

    /**
    * 全局异常处理类
    */
    @ControllerAdvice
    public class GlobalException {
        /**
         * 处理空指针异常
         * @param e
         * @return
         */
        @ExceptionHandler(value = {java.lang.NullPointerException.class})
        public ModelAndView nullpointExceptionHandler(Exception e){
    //        e对象会接收放错传入的异常对象
            ModelAndView mv = new ModelAndView();
            mv.addObject("err", e);
            mv.setViewName("error1");
            return mv;
        }
        /**
         * 处理算术异常
         * @param e
         * @return
         */
        @ExceptionHandler(value = {java.lang.ArithmeticException.class})
        public ModelAndView ArithmeticExceptionHandler(Exception e){
    //        e对象会接收放错传入的异常对象
            ModelAndView mv = new ModelAndView();
            mv.addObject("err", e);
            mv.setViewName("error2");
            return mv;
        }
    }
    

    当项目中出现空指针异常都会被该方法拦截并进行处理

    全局异常处理类有个缺点就是会定义特别多的方法来处理异常

    第四种,通过SimpleMappingExceptionResolver对象处理异常

    SimpleMappingExceptionResolve可以通过一个方法来处理多个不同的异常,并且跳转到不同的页面

    /**
    * 全局异常
    * SimpleMappingExceptionResolver
    */
    @Configuration
    public class GloballException2 {
        /**
         * 此方法返回值必须是SimpleMappingExceptionResolver,方法名可以随意
         * @return
         */
        @Bean
        public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
            //简单映射异常解析,也是可以根据异常类型和需要跳转视图做一个映射处理
            SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
            Properties properties = new Properties();
            /**
             * 参数1:异常类型(全名)
             * 参数2:跳转页面(视图)
             */
            //这里只是做,视图与异常类型的映射,并没有传递异常对象,所以跳转到对应的视图后并没有传递异常对象过去
            properties.put("java.lang.NullPointerException","error3");
            properties.put("java.lang.ArithmeticException","error4");
            resolver.setExceptionMappings(properties);
            return resolver;
        }
    }
    

    error3.html

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        出错了。。。空指针异常
    </body>
    </html>
    

    error4.html

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
    <head>
        <meta charset="UTF-8">
        <title>error2</title>
    </head>
    <body>
        出错了。。。算术异常
    </body>
    </html>
    

    缺点:只能做异常和视图的映射,不能获取到异常信息

    第五种,通过自定义HandlerExceptionResolver对象处理异常

    • 创建全局异常处理类

    全局异常处理类 GloballException3

    /**
    * 自定义HandlerExceptionResolve对象处理异常
    * 必须要实现HandlerExceptionResolver
    */
    @Configuration
    public class GloballException3 implements HandlerExceptionResolver{
        @Override
        public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e) {
            ModelAndView mv = new ModelAndView();
            //判断不同异常类型,做不同视图的跳转
            if(e instanceof NullPointerException){
               mv.setViewName("error5");
            }
            if(e instanceof ArithmeticException){
                mv.setViewName("error6");
            }
            //不管跳到哪个视图,携带的异常信息不变所以不用带入if判断里面
            mv.addObject("error", e.toString());
            return mv;
        }
    }
    

    error5.html

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
    <head>
        <meta charset="UTF-8">
        <title>error5</title>
    </head>
    <body>
        出错了。。。空指针异常
        <span th:text="${error}"></span>
    </body>
    </html>
    

    error6.html

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <link rel="shortcut icon" href="../resources/favicon.ico" th:href="@{/static/favicon.ico}" />
    <head>
        <meta charset="UTF-8">
        <title>error6</title>
    </head>
    <body>
        出错了。。。算术异常
        <span th:text="${error}"></span>
    </body>
    </html>
    
  • 相关阅读:
    《第一行代码》阅读笔记(十四)——ViewPager
    《第一行代码》阅读笔记(十三)——碎片的最佳案例
    《第一行代码》阅读笔记(十二)——探究碎片
    《第一行代码》阅读笔记(十一)——编写界面的最佳案例
    《第一行代码》阅读笔记(十)——RecyclerView
    《第一行代码》阅读笔记(九)——ListView
    《第一行代码》阅读笔记(八)——自定义控件
    《第一行代码》阅读笔记(七)——Android经典四种布局
    《第一行代码》阅读笔记(六)——AndroidUI控件(初级)
    后台管理系统左侧菜单栏显示隐藏
  • 原文地址:https://www.cnblogs.com/Ryuichi/p/13455982.html
Copyright © 2020-2023  润新知