Spring Boot异常处理

1 Spring Boot默认异常提示

在Spring Boot应用执行过程中难免会出现各种错误,默认情况下,只要出现异常,就会跳转到Spring Boot默认错误提示页面,如下:

为了给用户更好的体验,我们可以使用以下四种手段来优化异常捕获的情况。

2 自定义error的错误页面

刚才我们已经知道SpringBoot应用默认已经提供一套错误处理机制:就是把所有后台错误统一交给error请求,然后跳转到了本身自己的错误提示页面。这时,我们重新建立了一个新的error.html,该页面必须放在resources的templates目录下,如下:

error.html内容如下:

<!DOCTYPE html>
<html>
<head>
    <title th:text="${title}"></title>
</head>
<body>
<div >
    <div>
        <div>
            <p><span class="code" th:text="${status}"></span>非常抱歉,页面出现错误</p>
            <a href="/" class="btn-back common-button">返回首页</a>
            <div >
                <div th:text="${#dates.format(timestamp,'yyyy-MM-dd HH:mm:ss')}"></div>
                <div th:text="${messages}"></div>
                <div th:text="${error}"></div>
            </div>
        </div>
    </div>
</div>
</body>

上面的页面用到了Thymeleaf,所以项目中需要导入Thymeleaf的依赖

<!-- 导入thymeleaf坐标 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

这样,只要应用一出错就会跳转到error.html页面:

 

源码下载:https://pan.baidu.com/s/1wT-UrAb-DwFfctu37FArwg

 

3 @ExceptionHandler注解

3.1 @ExceptionHandler简介

@ExceptionHandler源码

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
    Class<? extends Throwable>[] value() default {};
}

从源码中可以看出,@ExceptionHandler 注解只能作用为对象的方法上,并且在运行时有效,value() 可以指定异常类。由该注解注释的方法可以具有灵活的输入参数。

3.2 具体代码示例

package com.yiidian.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

/**
 * 控制器
 * 一点教程网 - www.yiidian.com
 */
@Controller
public class HelloController {

    @RequestMapping("/hello1")
    @ResponseBody
    public String hello1(){
        //模拟java.lang.ArithmeticException异常
        int i = 10/0;
        return "欢迎来到一点教程网";
    }

    @RequestMapping("/hello2")
    @ResponseBody
    public String hello2(){
        //模拟java.lang.NullPointerException异常
        String name=null;
        name.trim();
        return "欢迎来到一点教程网";
    }

    // 处理java.lang.ArithmeticException
    @ExceptionHandler(value = { java.lang.ArithmeticException.class })
    @ResponseBody
    public String handlerArithmeticException(Exception e) { // e:该对象包含错误信息
        return "数学运算错误:"+e.getMessage();
    }

    // 处理java.lang.NullPointerException
    @ExceptionHandler(value = { java.lang.NullPointerException.class })
    @ResponseBody
    public String handlerNullPointerException(Exception e) { // e:该对象包含错误信息
        return "空指针错误:"+e.getMessage();
    }
}

3.3 运行效果

源码下载:https://pan.baidu.com/s/1ztcuBj9n-l8EC42yxCp55w

4 @ControllerAdvice注解

刚才的@ExceptionHandler注解是用在控制器类里面的,这样每个控制器都需要定义相关方法,比较繁琐。这时可以使用@ControllerAdvice来抽取所有共同的@ExceptionHandler方法,从而简化异常方法的定义。

代码如下:

package com.yiidian.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 自定义全局异常处理类
 * 一点教程网 - www.yiidian.com
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    // 处理java.lang.ArithmeticException
    @ExceptionHandler(value = { java.lang.ArithmeticException.class })
    @ResponseBody
    public String handlerArithmeticException(Exception e) { // e:该对象包含错误信息
        return "数学运算错误:"+e.getMessage();
    }

    // 处理java.lang.NullPointerException
    @ExceptionHandler(value = { java.lang.NullPointerException.class })
    @ResponseBody
    public String handlerNullPointerException(Exception e) { // e:该对象包含错误信息
        return "空指针错误:"+e.getMessage();
    }
}

执行效果和第二种方案是一样的!

 

源码下载:https://pan.baidu.com/s/1h8RukAS9CyritQ1Ag-W4jw

5 HandlerExceptionResovler

5.1 定义全局异常类

package com.yiidian.controller;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义异常处理类
 * 一点教程网 - www.yiidian.com
 */
@Configuration
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {

    @Override
    public ModelAndView resolveException(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2,
                                         Exception e) {
        ModelAndView mv = new ModelAndView();
        //判断不同异常类型,做不同处理
        if(e instanceof ArithmeticException){
            mv.setViewName("error1");
        }

        if(e instanceof NullPointerException){
            mv.setViewName("error2");
        }

        mv.addObject("error", e.toString());
        return mv;
    }

}

5.2 建立error页面

内容如下:

error1.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自定义错误页面</title>
</head>
<body>
<h3>错误页面-ArithmeticException</h3>
<div th:text="${exception}"></div>
</body>
</html>

error2.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>自定义错误页面</title>
</head>
<body>
<h3>错误页面-NullPointerException</h3>
<div th:text="${exception}"></div>
</body>
</html>

5.3 运行测试

 

源码下载:https://pan.baidu.com/s/1fpLJmTFrqcUm_EALKozyIw

热门文章

优秀文章