Spring Boot---(12)SpringBoot中自定义异常的使用

 

SpringBoot中自定义异常的使用

在javaweb应用程序中,如果程序中出现了异常,页面会直接报500,404等错误。但是如果给出这种页面给用户看,用户体验肯定不太好,我们可以使用自定义的异常,换一种页面给用户看。

 

在没有经过任何处理的时候

不存在的页面,抛出404异常

Spring Boot---(12)SpringBoot中自定义异常的使用

程序出现问题的时候,抛出500异常

Spring Boot---(12)SpringBoot中自定义异常的使用

做一个最简单的处理,就是在resources/templates中添加一个error.html页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>错误页面提示</title>
</head>
<body>
    出错了,请与管理员联系。
    <span th:text="${exception}"></span>
</body>
</html>

找不到页面,或是页面出现页面时候可以由error.html页面展示给用户查看,但是,这样,你根本就不知道你具体的异常是什么,只知道报错。只能去后台查看日志才能知道是什么原因导致出现了错误,springboot中有全局异常处理,可以定义到具体的异常。

Spring Boot---(12)SpringBoot中自定义异常的使用

SpringBoot默认的处理异常的机制:

SpringBoot默认的已经提供一套处理异常的机制。一旦程序中出现了异常SpringBoot会像/error的url发送请求,在SpringBoot中提供了一个叫BasicExceptionController来处理/error请求,然后跳转到默认显示异常来展示异常信息。

先把基本的代码贴出,再一个个做测试

pom.xml的依赖包,不需要额外添加别的依赖包

<dependencies>
        <!-- springBoot的启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- thymeleaf的启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
    </dependencies>

页面,index.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        我有这个页面
</body>
</html>

页面,error.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>错误页面提示</title>
</head>
<body>
    出错了,请与管理员联系。
    <span th:text="${exception}"></span>
</body>
</html>

 页面,error1.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>错误提示页面:ArithmeticException</title>
</head>
<body>
出错了,请与管理员联系。
<span th:text="${exception}"></span>
</body>
</html>

 页面,error2.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>错误提示页面:NullPointerException</title>
</head>
<body>
    出错了,请与管理员联系。
    <span th:text="${exception}"></span>
</body>
</html>

启动类

package com.kevin;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author kevin
 * @version 1.0
 * @description     SpringBoot的异常处理
 *
 *      SpringBoot默认的处理异常的机制:SpringBoot默认的已经提供一套处理异常的机制。
 *      一旦程序中出现了异常SpringBoot会像/error的url发送请求,在SpringBoot中提供了一个
 *      叫BasicExceptionController来处理/error请求,然后跳转到默认显示异常来展示异常信息。
 * @createDate 2019/3/22
 */
@SpringBootApplication
public class ExceptionApplication {

    public static void main(String[] args) {
        SpringApplication.run(ExceptionApplication.class,args);
    }
}

自定义错误的页面

package com.kevin.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author kevin
 * @version 1.0
 * @description     SpringBoot处理异常方式一:自定义错误页面
 * @createDate 2019/3/22
 */
@Controller
public class DemoController {

    @RequestMapping("/show")
    public String showInfo(){
        String str = null;
        str.length();
        return "index";
    }

    @RequestMapping("/show2")
    public String showInfo2(){
        int a = 10/0;
        return "index";
    }

    @RequestMapping("/show3")
    public String showInfo3(){
        return "index";
    }



}

方式一:ExceptionHandler+ControllerAdvice的全局异常处理类

package com.kevin.controller;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;


/**
 * @author kevin
 * @version 1.0
 * @description     ExceptionHandler+ControllerAdvice的全局异常处理类
 * @createDate 2019/3/22
 */
@ControllerAdvice
public class GlobalException {

    /**
     * java.lang.ArithmeticException.class
     *     该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图指定
     * @param e:会将产生异常对象注入到方法中
     * @return
     */
    @ExceptionHandler(value={java.lang.ArithmeticException.class})
    public ModelAndView arithmeticExceptionHandler(Exception e){
        ModelAndView mv = new ModelAndView();
        mv.addObject("error",e.toString());
        mv.setViewName("error1");
        return mv;
    }

    /**
     *  java.lang.NullPointerException.class
     *      该方法需要返回一个 ModelAndView: 目的是可以让我们封装异常信息以及视图的指定
     * @param e:会将产生异常对象注入到方法中
     * @return
     */
    @ExceptionHandler(value={java.lang.NullPointerException.class})
    public ModelAndView nullPointerExceptionHandler(Exception e){
        ModelAndView mv = new ModelAndView();
        mv.addObject("error",e.toString());
        mv.setViewName("error2");
        return mv;
    }

}

方式二:通过实现HandlerExceptionResolver接口做全局异常处理

package com.kevin.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;

/**
 * @author kevin
 * @version 1.0
 * @description     通过实现HandlerExceptionResolver接口做全局异常处理
 * @createDate 2019/3/22
 */
@Configuration
public class HandlerException implements HandlerExceptionResolver {

    // 通过实现HandlerExceptionResolver接口做全局异常处理
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
                                         HttpServletResponse response, Object handler,
                                         Exception ex) {
        ModelAndView mv = new ModelAndView();
        //判断不同异常类型, 做不同视图跳转
        if(ex instanceof ArithmeticException){
            mv.setViewName("error1");
        }
        if(ex instanceof NullPointerException){
            mv.setViewName("error2");
        }
        mv.addObject("error", ex.toString());
        return mv;
    }
}

方式三:通过SimpleMappingExceptionResolver做全局异常处理

package com.kevin.controller;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import java.util.Properties;

/**
 * @author kevin
 * @version 1.0
 * @description     通过SimpleMappingExceptionResolver做全局异常处理
 * @createDate 2019/3/22
 */
@Configuration
public class SimpleMappingException {

    /**
     * 该方法必须要有返回值。 返回值类型必须是:SimpleMappingExceptionResolver
     */
    @Bean
    public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties mappings = new Properties();
        // 参数一: 异常的类型, 注意必须是异常类型的全名
        // 参数二: 视图名称
        mappings.put("java.lang.ArithmeticException", "error1");
        mappings.put("java.lang.NullPointerException","error2");
        //设置异常与视图映射信息的
        resolver.setExceptionMappings(mappings);
        return resolver;
    }
}

测试自定义错误的页面,空指针异常

Spring Boot---(12)SpringBoot中自定义异常的使用

测试不存在的url地址

Spring Boot---(12)SpringBoot中自定义异常的使用

测试自定义错误的页面:数学运算异常

Spring Boot---(12)SpringBoot中自定义异常的使用

测试成功的页面

Spring Boot---(12)SpringBoot中自定义异常的使用