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

智能推荐

时间秒数转为hhmmss格式_hhmmss时间格式转换-程序员宅基地

文章浏览阅读1.8k次。文章目录一、将秒转为hhmmss一、将秒转为hhmmss代码如下(示例):std::string sec2hhmmss(int sec){ int hour = sec/3600; int min=(sec%3600)/60; int second=(sec%3600)%60; std::string h=std::to_string(hour); std::string m=std::to_string(min); std::string s=std::to_string(sec_hhmmss时间格式转换

13、三维图绘制及添加文本_plt.plot 三维图-程序员宅基地

文章浏览阅读2.7k次,点赞4次,收藏13次。目录1、简述2、3D line plot3、3D Scatter plot4、三维等高线图(3D Contour Plot)5、三维线框图(3D Wireframe plot)6、三维曲面图(3D Surface plot)7、添加文本(Working With Text)1、简述尽管Matplotlib最初设计时只考虑了二维绘图,但在后来的版本中,在Matplotlib的二维显示基础上建立了一些三维绘图实用程序,为三维数据可视化提供了一套工具。通过导入Matplotlib软件包中包含的mplot3d工_plt.plot 三维图

Flex之正在等待Adobe Flash Player 连接调试器..._adobe flex ocx-程序员宅基地

文章浏览阅读1.8k次。环境:Flash Bulider 4问题:运行调试的时候,进度窗口提示"正在等待Adobe Flash Player 连接调试器...",进度为57%分析:出现该问题的原因是没有安装Adobe Flash Player调试器解决:安装Adobe Flash Player调试器下载_adobe flex ocx

Hexo部署博客到Github和Coding,看这一篇就够了_coding github hexo 博客-程序员宅基地

文章浏览阅读2.5k次。前言这是一篇很详细的独立博客搭建教程,意在帮助小白们能快速入门,拥有自己的独立博客。作者已在window平台已搭建成功,博客效果请点链接查看。 为什么用Hexo搭建独立博客?Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。Github和Coding又是什么?Github是..._coding github hexo 博客

c++从txt文件读取一个矩阵数据_c++如何读取文件中的双精度浮点矩阵-程序员宅基地

文章浏览阅读7.2k次,点赞8次,收藏27次。#include <iostream>#include <vector>#include <fstream>#include <zconf.h>#include <string>#include <sstream>std::vector<std::vector<double >> readMatrixFile(const char *fileName) { // get current ._c++如何读取文件中的双精度浮点矩阵

bootstrap导航元素(14)_bootstrap 导航元素-程序员宅基地

文章浏览阅读177次。表格导航或标签创建一个标签式的导航菜单:以一个带有 class .nav 的无序列表开始。添加 class .nav-tabs。&lt;p&gt;标签式的导航菜单&lt;/p&gt;&lt;ul class="nav nav-tabs"&gt; &lt;li class="active"&gt;&lt;a href="#"&gt;Home&lt;_bootstrap 导航元素

随便推点

spring cloud gateway全局过滤器 向request header中放数据_gateway中在header中添加信息-程序员宅基地

文章浏览阅读4.4w次,点赞20次,收藏46次。exchange.getRequest().getHeaders().set(); 是不能向 headers中放文件的这时配置一个gateway全局过滤器 filter中 做了向 header放数据/** * @Description 全局过滤器 在这里可以实现记录日志和访问权限校验等 * @Author [email protected] * @Created D..._gateway中在header中添加信息

OSError: [WinError 127] 找不到指定的程序 问题解决 无需修改文件路径配置 简单操作(与torch安装有较大关系)_oserror: [winerror 127] 找不到指定的程序。-程序员宅基地

文章浏览阅读2w次,点赞13次,收藏36次。遇到这类问题往往跟torch安装的工具包(如torch-scattertorch-sparsetorch-cluster 1.4.5)版本没对应上有关,以我安装的torch为1.8.0+CPU为例,_oserror: [winerror 127] 找不到指定的程序。

TP-LINK无线路由器配置解读-程序员宅基地

文章浏览阅读556次。我是一个喜欢自己给自己挖坑的人,什么东西都要动两榔头,后来发现吃到苦头了,但是这个东西也成为所谓的收获,下次就长记性了,其实我是最不长记性的人,但是为了使其能够作为参考,以备后面遗忘了,还是写一下吧,记性这东西不用就很容易遗忘,像这个无线路由器,一般公司基本上一年到头才碰到1~2回,但是对我目前这份工作来说,好像很平常的样子,时不时网络有问题,大多数情况总跟无线路由器有关系,好啦我就一一的记录下来..._tplink 路由器 解析配置文件

voc格式数据集转yolo格式数据可视化桌面小工具_voc数据集标注可视化-程序员宅基地

文章浏览阅读102次。此工具为个人开发的、用于voc数据集划分和转化为coco格式数据的可视化桌面程序,voc划分数据集、转coco格式傻瓜式操作!选择训练集-测试集划分比例(第一项),如果数据集比较大,可以从训练集中再划分一个小的验证集,用于训练时验证,加快训练流程。点击“voc数据集划分”按钮进行划分数据集,点击“voc数据集标签统计”可查看划分数据的情况。选择VOC数据集所在的文件夹和保存转换为coco格式的文件夹。点击转换按钮,将得到coco格式的数据集。图1 voc数据集文件夹模板。图 6 数据划分情况。_voc数据集标注可视化

亚马逊广告接口 amazon advert api 申请流程_php /v2/reports/{reportid}/download-程序员宅基地

文章浏览阅读7.1k次,点赞4次,收藏10次。#亚马逊广告接口 amazon advert api 申请流程申请连接 : https://advertising.amazon.com/about-api然后会有 亚马逊的人员和你做邮件来往 不啦不啦问一圈 然后会给你授权授权邮件的大概样式获得到授权后 操作官方链接如下 https://advertising.amazon.com/API/docs/en-us/setting..._php /v2/reports/{reportid}/download

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'jffa.QRTZ_TRIGGERS' doesn't exist_table 'uip_basics.qrtz_triggers’-程序员宅基地

文章浏览阅读7.8k次,点赞2次,收藏2次。场景:看过 人人 快速开发的都明白,这里面有很多qrtz_开头的11个表,这些表不是业务表,是定时任务的辅助表。情况是这样的,我在线下,利用的是人人这同一套代码,个人博客的表什么的都新建好了,线下测试也没有问题,上线的时候,抛出这一段错误:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'jffa.QRTZ_TR..._table 'uip_basics.qrtz_triggers’