Java异常分类及统一处理详解

 更新时间:2016年03月28日 15:57:20   作者:边号007  
这篇文章主要为大家详细介绍了Java异常分类及统一处理,SpringMVC处理异常支持ajax,web.xml配置异常,感兴趣的小伙伴们可以参考一下

一、异常分类

       java异常分为"检查"和"非检查"两类,"检查"二字的意思是,代码编译时,编译器会去Check一下有没有进行异常处理(捕获或向上抛),对于归类为需要检查的异常,若没处理,编译就过不去。
       初学的时候,常常想为啥异常要这样分类处理? 后来明白了些,异常不过两种:主观和客观,一个大多数情况下可以避免,一个大多数情况下无法避免。
       像NullPointerException这类异常,大多跟程序员素质挂钩(开发好,测试好, 基本不会在系统运行后蹦出来), 基本是可以避免的,java语法当初把它们对类为‘非检查异常',也算给程序员和编译器省了不少事;
      而像IOException这类跟外在环境有关的异常,几乎是不可避免的(指不定哪一天那一秒网络就挂了),但是当不期而遇时,程序还是要有所作为,所以编译器有必要督促一下程序员,Check一下,看看是是否对这些可能不期而至的异常进行了处理。当Exception对象传递到某个节点后,程序就可以执行一些措施了,比如:给用户返回一个提示("系统繁忙,请重试"),给监控平台推送一个异常消息等等。

二、异常的统一返回处理

1、容器处理

下面列举Tomcat的处理方式,在web.xml下配置,按http返回码或Exception类型来处理:

<error-page>
 <error-code>404</error-code>
 <location>/WEB-INF/views/error/404.jsp</location>
 </error-page>
 
 <error-page>
 <error-code>500</error-code>
 <location>/WEB-INF/views/error/500.jsp</location>
 </error-page> 
 
 <error-page>
 <exception-type>java.lang.Throwable</exception-type>
 <location>/WEB-INF/views/error/throwable.jsp</location>
 </error-page>

缺点:无法处理不需要返回html的请求,比如ajax;

2、框架处理

下面列举Spring MVC的处理方式

(1)使用Spring MVC自带的简单异常处理器SimpleMappingExceptionResolver;
(2)实现接口HandlerExceptionResolver 自定义异常处理器; (建议使用,可支持ajax等扩展)
(3)使用@ExceptionHandler注解实现异常处理;

第(1)种,在spring-mvc.xml下配置

 <!-- 将Controller抛出的异常转到特定视图 -->
 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
  <property name="exceptionMappings">
   <props>
    <!-- 不同异常分开跳转--> 
    <!-- 可以自定义不同的异常-->    
    <prop key="com.test.MyException1">/error/e1</prop>
    <prop key="com.test.MyException2">/error/e2</prop>
    <!-- 如果不想自定义异常,只配置下面的即可--> 
    <prop key="java.lang.Throwable">/error/500</prop>
   </props>
  </property>
 </bean>

缺点:无法处理不需要返回html的请求; 

 第(2)种,自定义HandlerExceptionResolver接口的实现类

/**
 * 自定义异常处理器:支持ajax
 * @author wangxu
 *
 */
public class MyExceptionHandler implements HandlerExceptionResolver {
 
 public ModelAndView resolveException(HttpServletRequest request,
 HttpServletResponse response, Object handler, Exception ex) {
 
 /* 区分ajax */
 boolean isAjax = request.getHeader("X-Requested-With") != null
 && "XMLHttpRequest".equals(request
  .getHeader("X-Requested-With").toString());
 if (!isAjax) {
 if (ex instanceof com.test.MyException1) {
 return new ModelAndView("/error/e1");
 } else if (ex instanceof com.test.MyException1) {
 return new ModelAndView("/error/e2");
 } else {
 return new ModelAndView("/error/500");
 }
 }
 String jsonRes = "{\"message\":\"" + "系统异常" + "\"}";// 自定义结构和前台对接
 PrintWriter out = null;
 try {
 out = response.getWriter();
 request.setCharacterEncoding("utf-8");
 response.setContentType("text/plain;charset=utf-8");
 out.print(jsonRes);
 out.flush();
 } catch (IOException e) {
 e.printStackTrace();
 } finally {
 out.close();
 }
 return null;
 }
}

并在spring-mvc.xml下注册处理器

<bean id="exceptionHandler" class="com.test.MyExceptionHandler"/>
优点:可以处理ajax请求,也方便编码实现功能扩展,比如异常的监控等。

第(3)种,@ExceptionHandler注解

@Controller
public class TestExceptionHandlerController {
 
 @ExceptionHandler({ MyException1.class })
 public String exception(MyException1 e) {
 return "/error/e1";
 }
 @RequestMapping("/marry")
 public void test() {
 throw new MyException1("没钱!");
 }
}

缺点:@ExceptionHandler的方法,必须和可能抛异常的方法在一同个Controller下。(不建议使用)

3、结合

实际项目中,在处理异常的统一返回时,会将一些自定义的异常或者扩展交给框架,将http返回码的映射交给容器,因为http返回码更外层,有些到不了框架,有些对于框架来说就不是一个异常(比如404之与Spring MVC)。框架是运行在容器里的,当框架优先拿到异常并做了返回处理,容器就不会再进行映射。

以上就是本文的全部内容,希望对大家的学习有所帮助。

相关文章

  • springboot 整合fluent mybatis的过程,看这篇够了

    springboot 整合fluent mybatis的过程,看这篇够了

    这篇文章主要介绍了springboot 整合fluent mybatis的过程,配置数据库连接创建数据库的详细代码,本文给大家介绍的非常详细,需要的朋友可以参考下
    2021-08-08
  • Java内部类原理与用法实例总结

    Java内部类原理与用法实例总结

    这篇文章主要介绍了Java内部类原理与用法,结合实例形式总结分析了非静态内部类、静态内部类、局部类等相关概念、原理、用法及相关操作注意事项,需要的朋友可以参考下
    2018-08-08
  • Java简单使用EasyExcel操作读写excel的步骤与要点

    Java简单使用EasyExcel操作读写excel的步骤与要点

    相信现在很多搞后端的同学大部分做的都是后台管理系统,那么管理系统就肯定免不了Excel的导出导入功能,下面这篇文章主要给大家介绍了关于Java简单使用EasyExcel操作读写excel的步骤与要点,需要的朋友可以参考下
    2022-09-09
  • Java并发框架中的AQS详细解析

    Java并发框架中的AQS详细解析

    这篇文章主要介绍了Java并发框架中的AQS详细解析,之前说锁的升级的时候,说到了自旋锁会空转几次尝试等待获取资源,其实这一系列的动作是有一个规范的这个规范叫做同步发生器AbstractQueuedSynchronizer ,简称AQS,需要的朋友可以参考下
    2024-01-01
  • MapReduce中ArrayWritable 使用指南

    MapReduce中ArrayWritable 使用指南

    MapReduce是一种编程模型,用于大规模数据集的并行运算。概念"Map(映射)"和"Reduce(归约)"和他们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。他极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。
    2014-08-08
  • 基于java类路径classpath和包的实例讲解

    基于java类路径classpath和包的实例讲解

    下面小编就为大家分享一篇基于java类路径classpath和包的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Spring batch批处理框架

    Spring batch批处理框架

    本文主要介绍了Spring batch批处理框架的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-04-04
  • Java线程同步及实现方法详解

    Java线程同步及实现方法详解

    这篇文章主要介绍了Java线程同步及实现方法详解,当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常,需要的朋友可以参考下
    2023-11-11
  • SpringBoot如何实现并发任务并返回结果

    SpringBoot如何实现并发任务并返回结果

    这篇文章主要介绍了SpringBoot如何实现并发任务并返回结果问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • SpringBoot集成RabbitMQ和概念介绍

    SpringBoot集成RabbitMQ和概念介绍

    这篇文章主要介绍了SpringBoot集成RabbitMQ和概念介绍,RabbitMQ即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。更多相关内容需要的小伙伴可以参考一下下面文章内容
    2022-05-05

最新评论