springboot的异常处理-设置全局异常处理

一.说明

1.1 异常处理的5种方式

1.自定义错误页面  
2.使用注解@ExeceptionHandler 
3.使用@ControllerAdvice+@HadlerException 实现全局异常的处理
4.使用SimpleMappingExceptionResult全局异常处理类
5.使用HandlerExceptionResolver自定义全局处理异常类

1.2 全局异常设置@ControllerAdvice+@ExceptionHandler

通过注解@ControllerAdvice 定义一个处理全局 异常的类,在需要捕捉异常的方法上加上@ExceptionHandler(value=Exception.class)这个注解。

@ControllerAdvice 如果是返回json数据 则用 RestControllerAdvice,就可以不加 @ResponseBody

如下图

二 案例操作

2.1 执行逻辑

配置一个检测异常的全局类,发生异常时,根据配置的code,msg,url等信息,以json串的形式,返回的前端,进行友好的提示。

2.2 项目的结构

2.3 搭建项目

2.3.1 pom文件

    <!-- springBoot 的启动器 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
package com.ljf.spring.boot.demo.controller;


import com.ljf.spring.boot.demo.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;

/**
 * @ClassName: UserController
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/03/26 11:24:40 
 * @Version: V1.0
 **/
@Controller
public class UserController {
    @RequestMapping("/showUser")
    @ResponseBody
    public Object showUser(Model model){
        System.out.println("controller进来了");
        //int k=5/0;
        return new User(11, "sfsfds", "1000000", new Date());

    }
}

2.3.2 model

package com.ljf.spring.boot.demo.model;

import java.util.Date;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;

public class User {

	private int age;
	
	@JsonIgnore
	private String pwd;
	
	@JsonProperty("account")
	@JsonInclude(Include.NON_NULL)
	private String phone;
	
	@JsonFormat(pattern="yyyy-MM-dd hh:mm:ss",locale="zh",timezone="GMT+8")
	private Date createTime;

	
	
	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public User() {
		super();
	}

	public User(int age, String pwd, String phone, Date createTime) {
		super();
		this.age = age;
		this.pwd = pwd;
		
		this.createTime = createTime;
	}

	
	
	
}

2.3.3 启动类

package com.ljf.spring.boot.demo;

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

@SpringBootApplication
public class App
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
        System.out.println( "Hello World!" );
    }
}

2.4 正常访问

2.4.1 启动访问

ok,通过这样访问没有问题。

2.5 方法一:springboot默认异常处理

在controller,设置int k/0,让程序报错,springboot,会给出一个空白页提示出现错误,不太友好,如下图

2.6 方法二:使用@ControllerAdvice+@HadlerException 实现全局异常的处理

2.6.1 定义一个处理异常的类

package com.ljf.spring.boot.demo.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: CustomerException
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/03/26 11:39:01 
 * @Version: V1.0
 **/

@RestControllerAdvice  //@ControllerAdvice 如果是返回json数据 则用 RestControllerAdvice,就可以不加 @ResponseBody
public class CustomerException {
    private static final Logger LOG = LoggerFactory.getLogger(CustomerException.class);
    //捕获全局异常,处理所有不可知的异常
    @ExceptionHandler(value=Exception.class)
    Object handleException(Exception e, HttpServletRequest request){
        LOG.error("url {}, msg {}",request.getRequestURL(), e.getMessage());
        Map<String, Object> map = new HashMap<>();
        map.put("code", 400);
        map.put("msg", "错误信息如下:"+e.getMessage());
        map.put("url", "请求地址:"+request.getRequestURL());
        return map;
    }
   
}

2.6.2 再次访问

实现了我们想要的结果,返回错误信息的提示。

2.6.3 根据不同异常,返回不同提示信息

1.controller类:

2.全局异常类:

package com.ljf.spring.boot.demo.exception;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName: CustomerException
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/03/26 11:39:01 
 * @Version: V1.0
 **/

@RestControllerAdvice  //@ControllerAdvice 如果是返回json数据 则用 RestControllerAdvice,就可以不加 @ResponseBody
public class CustomerException {
    private static final Logger LOG = LoggerFactory.getLogger(CustomerException.class);
    //捕获全局异常,处理所有不可知的异常
    @ExceptionHandler(value=Exception.class)
    Object handleException(Exception e, HttpServletRequest request){
        LOG.error("url {}, msg {}",request.getRequestURL(), e.getMessage());
        Map<String, Object> map = new HashMap<>();
        map.put("code", 400);
        map.put("msg", "错误信息如下:"+e.getMessage());
        map.put("url", "请求地址:"+request.getRequestURL());
        return map;
    }
    /**
     * java.lang.ArithmeticException
     * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
     * 参数Exception e:会将产生异常对象注入到方法中
     */
    @ExceptionHandler(value={java.lang.ArithmeticException.class})
    public Object arithmeticExceptionHandler(Exception e,HttpServletRequest request){
        LOG.error("url {}, msg {}",request.getRequestURL(), e.getMessage());
        Map<String, Object> map = new HashMap<>();
        map.put("code", 401);
        map.put("msg", "错误信息如下:"+e.getMessage());
        map.put("url", "请求地址:"+request.getRequestURL());
        return map;
    }

    /**
     * java.lang.NullPointerException
     * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
     * 参数Exception e:会将产生异常对象注入到方法中
     */
    @ExceptionHandler(value={java.lang.NullPointerException.class})
    public Object nullPointerExceptionHandler(Exception e,HttpServletRequest request){
        LOG.error("url {}, msg {}",request.getRequestURL(), e.getMessage());
        Map<String, Object> map = new HashMap<>();
        map.put("code", 402);
        map.put("msg", "错误信息如下:"+e.getMessage());
        map.put("url", "请求地址:"+request.getRequestURL());
        return map;
    }

}

2.6.4 再次访问

算术异常:

空指针异常:

2.6 方法三:使用@SimpleMappingExceptionResolver实现全局异常的处理 

2.6.1 controller类

package com.ljf.spring.boot.demo.controller;

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

/**
 * @ClassName: ExceptionController
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/03/07 12:07:43 
 * @Version: V1.0
 **/
@Controller
public class ExceptionController {
    @RequestMapping("/show")
    public String showInfo(){
        String str = null;
        str.length();
        return "index";
    }

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

}

2.6.2 定义全局异常处理类

package com.ljf.spring.boot.demo.exception;

/**
 * @ClassName: GlobalException
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/03/27 11:15:18 
 * @Version: V1.0
 **/

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

import java.util.Properties;

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

2.6.3 定义页面

1.error-kong页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>出现空指针异常......<span th:text="${exception}"></span></h1>
</body>
</html>

2.error-sushu页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>出现算术异常了!!!!<span th:text="${exception}"></span></h1>
</body>
</html>

2.6.4 页面访问

1.算术异常

2.空指针异常

2.7 方法四:自定义HandlerExceptionResolver实现处理异常

2.7.1 编写自定义的全局异常处理类

执行的时候,将之前编写的全局异常处理类,进行注释掉

package com.ljf.spring.boot.demo.exception;

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;

/**
 * @ClassName: GloabalExceptionByDefine
 * @Description: TODO
 * @Author: liujianfu
 * @Date: 2021/03/27 12:12:32 
 * @Version: V1.0
 **/
@Configuration
public class GloabalExceptionByDefine implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
                                         Exception ex) {
        ModelAndView mv = new ModelAndView();
        //判断不同异常类型,做不同视图跳转
        if(ex instanceof ArithmeticException){
            mv.setViewName("error-kong");
        }

        if(ex instanceof NullPointerException){
            mv.setViewName("error-sushu");
        }
        mv.addObject("exception", ex.toString());

        return mv;
    }
}

2.7.2 访问

1.算术异常

2.空指针异常

猜你喜欢

转载自blog.csdn.net/u011066470/article/details/115237843