Java 异常分类及统一处理_java统一异常处理_酷酷的糖先森的博客-程序员秘密

技术标签: java  编译器  异常处理  J2EE  异常  class  

一、异常分类

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 tangqing
 *
 */
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)。框架是运行在容器里的,当框架优先拿到异常并做了返回处理,容器就不会再进行映射。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u014723529/article/details/53080974

智能推荐

基于Python开发WebService-1:服务端(spyne)_孙帅丨SUNSHUAI的博客-程序员秘密

目录1.基础环境2.基于spyne的服务端基于Python3、spyne工具包,开发WebService服务端1.基础环境Python3.7、spyne2.13.15pip install spyne2.基于spyne的服务端2.1、源码

dojo $F()_a11111111的博客-程序员秘密

$F() 是Form.Element.getValue()函数的缩写。$F()支持的输入控件包括系列(即type=submit/hidden/password/text/checkbox/radio),下拉列表控件和控件

linux内核打印数据包,基于Netfilter的Linux内核数据包处理_weixin_39556702的博客-程序员秘密

一、Netfilter介绍Netfilter是Linux操作系统核心层内部的一个数据包处理框架,可以在Linux内核中过滤、修改和封装数据包,Netfilter在IP报文处理流程中插入5个挂载点来,可以在挂载点注册处理数据包的回调函数,当数据包进入Linux内核经过挂载点的时候,会执行回调函数来处理数据包。二、Netfilter挂载点示意图NF_IP_PRE_ROUTING 在数据包...

checkbox属性checked=“checked“已有,但却不显示打勾的解决办法_"checked=\"checked"_烫头喝酒抽烟的博客-程序员秘密

主要原因是:jquery版本问题。1、attr():获取匹配的元素集合中的第一个元素的属性的值 或 设置每一个匹配元素的一个或多个属性。在jQuery 1.6中,当属性没有被设置时候,.attr()方法将返回undefined。若要检索和更改DOM属性,比如元素的checked, selected, 或 disabled状态,请使用.prop()方法。2、removeAttr():从每一个匹配的元素中删除一个属性1.6以下版本在IE6使用JQuery的removeAttr方法删除disabled

随便推点

java jtextfield 不显示_java JTextField为什么不能即使显示_gymsummer的博客-程序员秘密

这里有两个.JAVA文件。importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjava.awt.event.ItemEvent;importjava.awt.event.ItemListener;importjavax.swi...这里有两个.JAVA文件。import java.awt.event....

对外开放端口_qq-3191907415的博客-程序员秘密

1.定义:就是把本机当作服务器设定一个端口,在本机外通过"本机IP地址+服务器设定端口"即可访问到本机服务器。2.本机默认对外开放的端口:80端口3.实现方式:(Windows 10专业版,其他系统都是大同小异)a.在屏幕左下角输入框输入“防火墙”,打开“Windows Defender安全中心”界面的“防火墙和网络保护”模块。b.找到“高级设置”链接并点开c.屏幕出现“允许更改”对...

Spring Cloud自定义Consul相同服务多个实例注册被覆盖问题_consul 出现多个相同实例_TheGri1的博客-程序员秘密

Spring Cloud自定义Consul相同服务多个实例注册被覆盖问题问题:新建一个微服务 serviceA,在ip为[192.168.10.8]的机器上启动,Consul上查看当前服务正常的情况下,再从本地Ip或其他机器ip上启动serviceA服务,查看Consul发现原来的注册实例服务ip地址被覆盖了;分析问题:服务注册时,Consul是通过instance-id来区分服务实例的,...

nodejs 事件机制_dhxiyzqv45340的博客-程序员秘密

node 事件机制一 三种定时器NodeJS中有三种类型的定时器:超时时间、时间间隔、即时定时器1.超时时间:setTimeout(callback,delayMilliSeconds,[args])方法,如:setTimeout(myFunc,1000);setTimeout函数返回一个定时器对象的ID,可以在delayMilliSeconds...

TMS320F28335启动过程_大师兄电子工作室的博客-程序员秘密

1.DSP reset后运行的起始地址是多少?  0x3FFFC02.仿真器烧写程序的步骤是?  根据cmd文件把程序烧到指定位置,然后执行。3.DSP的Flash启动过程是什么?首先硬件配置GPIO84~87上拉为1,即处于Flash启动过程。当DSP复位后,会从复位向量0x3FFFC0处取得复位向量,并跳转到InitBoot处开始执行,InitBoot会读GPIO84~87

幸运抽奖_【幸运抽奖】编写一个幸运抽奖程序,使其能够在全班同学中随机抽取一位获奖同_编程小白2.0的博客-程序员秘密

幸运抽奖:本系统较为简单,未使用是什么多的算法,也未添加保存文件读取文件功能, 1、任务模拟注册登录幸运抽奖全过程2、主要功能:注册 登录 退出登录 抽奖 退出系统首页:输出菜单 选择菜单编号 如果编号选择错误,输出“您的输入有误!”注册:输入用户名和密码,系统产生4位随机数作为卡号。 注册成功,输出用户信息登录:输入注册时的用户名和密码,登录成功,系统提示登陆成功。 如果用户名和密码输入错误,提示用户继续输入。退出登录:若用户已登录...

推荐文章

热门文章

相关标签