Java异常分类及统一处理详解
作者:边号007 时间:2022-01-27 12:32:24
一、异常分类
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)。框架是运行在容器里的,当框架优先拿到异常并做了返回处理,容器就不会再进行映射。
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java fastdfs客户端实现上传下载文件
![](https://img.aspxhome.com/file/2023/0/59760_0s.png)
利用Java8 Optional类优雅如何地解决空指针问题
Java基础教程之HashMap迭代删除使用方法
Java异常--常见方法--自定义异常--增强try(try-with-resources)详解
WPF实现多运算符表达式计算器
![](https://img.aspxhome.com/file/2023/4/66574_0s.jpg)
秒懂Java枚举类型(enum)
掌握Android Handler消息机制核心代码
![](https://img.aspxhome.com/file/2023/7/87267_0s.jpg)
Spring Security中使用authorizeRequests遇到的问题小结
![](https://img.aspxhome.com/file/2023/2/64952_0s.png)
Java实现选择排序
![](https://img.aspxhome.com/file/2023/2/84602_0s.jpg)
Java开发微信公众号接收和被动回复普通消息
Java实现常用缓存淘汰算法:FIFO、LRU、LFU
C#清除字符串内空格的方法
![](https://img.aspxhome.com/file/2023/3/77243_0s.png)
java equals函数用法详解
Java SpringBoot的相关知识点详解
![](https://img.aspxhome.com/file/2023/0/58620_0s.png)
Java JVM字节码指令集总结整理与介绍
![](https://img.aspxhome.com/file/2023/9/71229_0s.png)
Spring-AOP @AspectJ进阶之如何绑定代理对象
![](https://img.aspxhome.com/file/2023/8/72388_0s.jpg)
Maven+Tomcat8 实现自动化部署的方法
关于EntityWrapper的in用法
![](https://img.aspxhome.com/file/2023/3/60353_0s.png)
Java实现TopK问题的方法
Java并发编程之JUC并发核心AQS同步队列原理剖析
![](https://img.aspxhome.com/file/2023/0/84620_0s.png)