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>
原文地址:https://www.cnblogs.com/Ryuichi/p/13455982.html