• SpringBoot 异常处理方式
    SpringBoot 中对于异常处理提供了五种处理方式:
  1. 自定义错误页面
    SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制。
    一旦程序中出现了异常 SpringBoot 会像/error 的 url 发送请求。在 springBoot 中提供了一个叫 BasicExceptionController 来处理/error 请求,然后跳转到默认显示异常的页面来展示异常
    信息.

如 果 我 们 需 要 将 所 有 的 异 常 同 一 跳 转 到 自 定 义 的 错 误 页 面 , 需 要 再 src/main/resources/templates 目录下创建 error.html 页面。注意:名称必须叫 error

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

  1. @ExceptionHandle 注解处理异常
/**
 * SpringBoot处理异常方式一:自定义错误页面
 *
 *
 */
@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";
	}
	
	/**
	 * java.lang.ArithmeticException
	 * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
	 * 参数Exception e:会将产生异常对象注入到方法中
	 */
	@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
	 * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
	 * 参数Exception e:会将产生异常对象注入到方法中
	 */
	@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;
	}
}

============================================

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>错误提示页面-NullPointerException</title>
	</head>
	<body>
		出错了,请与管理员联系。。。
		<span th:text="${error}"></span>
	</body>
</html>

  • 3.@ControllerAdvice+@ExceptionHandler 处理异常
    需要创建一个能够处理异常的全局异常类。 。 在该类上需要添加@ControllerAdvice 注解
/**
 * 全局异常处理类
 *
 *
 */
@ControllerAdvice
public class GlobalException {
	/**
	 * java.lang.ArithmeticException
	 * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
	 * 参数Exception e:会将产生异常对象注入到方法中
	 */
	@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
	 * 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
	 * 参数Exception e:会将产生异常对象注入到方法中
	 */
	@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;
	}
	
}

  • 4.配置SimpleMappingExceptionResolver
    在全局异常类中添加一个方法完成异常的统一处理
/**
 * 通过SimpleMappingExceptionResolver做全局异常处理
 *
 *
 */
@Configuration
public class GlobalException {
	
	/**
	 * 该方法必须要有返回值。返回值类型必须是: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;
	}
	
}

  • 4.配置SimpleMappingExceptionResolver
    在全局异常类中添加一个方法完成异常的统一处理
/**
 * 通过SimpleMappingExceptionResolver做全局异常处理
 *
 *
 */
@Configuration
public class GlobalException {
	
	/**
	 * 该方法必须要有返回值。返回值类型必须是: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;
	}
	
}

  • 5.自定义 HandlerExceptionResolver 类处理异常
    需要在全局异常处理类中实现 HandlerExceptionResolver
/**
 * 通过实现HandlerExceptionResolver接口做全局异常处理
 *
 *
 */
@Configuration
public class GlobalException implements 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;
	}
}

异常信息入库:

@Slf4j
@Aspect
@Component
public class ExceptionLogAspect {

    @Autowired
    private ExceMapper exceMapper;

    @Pointcut("execution(* cc.mrbird.febs.common.handler.GlobalExceptionHandler.*(..) )")
    public void pointcut(){}

    @Before("pointcut()")
    public void addInfo(JoinPoint joinPoint )
    {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        Object[] args = joinPoint.getArgs();
        Exception ex = (Exception) args[0];
        // 将异常信息写入数据库
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw, true));
        ExcetionMessage excetionMessage = new ExcetionMessage();
        excetionMessage.setOperTime(new Date());
        excetionMessage.setMessage(ex.getMessage());
        excetionMessage.setExecption(sw.toString());
        exceMapper.insert(excetionMessage);
    }

}