从零开始学 Java - Spring MVC 统一异常处理
看到 Exception 这个单词都心慌
如果有一天你发现好久没有看到Exception
这个单词了,那你会不会想念她?我是不会的。她如女孩一样的令人心动又心慌,又或者你已经练功到了孤独求败,等了半辈子终于看到了她,这时候你的小弟准备冲上去解决它说:大哥,我来解决它。你摆摆手说:还是我来最后一次吧...
从此,你再也没看到过Exception
了。
异常是个好东西
做开发的对异常在熟悉不过了,几乎是天天打交道的。记得当年写代码的时候记住的第一个异常是未将对象引用设置到对象的实例
,现在想想已经好久没有看到他了,当然这是 .Net 下的一个异常,对应 Java 下的是java.lang.NullPointerException
。
其实,异常并不可怕,可怕的是你不知道怎么解决它。 解决异常的方式有很多种,比如写好每一行代码,保证不出任何逻辑错误,就可以从根本上解决问题,但是,没有一个程序员能保证自己的代码不报异常,这也就是为什么会有 Bug
这个令人讨厌的东西了。当然,如果我们写的代码都没有异常,不出 Bug ,那怎么让我们有和测试妹子在一起工作的机会呢!哈哈哈...
既然我们保证不了从根本上解决代码不出异常的情况,那我们是谁阿,我们为了在测试妹子面前展示厉害到无敌的敲代码能力,我们就偷偷的在业务代码里使用 try...catch...
来让她看不出你写代码能力不行,你这时候就厉害到不行了,你脉脉看着她,她看着你...
难道不应该有即使我们不使用 try...catch...
也能捕获写出来的异常么?
这里有一本《异常秘籍》
并不是说使用 try...catch...
不行,是因为在程序里可能会有你可预知的异常,这时候你当然会去使用它来捕获异常,但是如果在一个你不可预知的方法里,你本能认为它不会出异常,你还会使用 try...catch...
去捕获么?如果你回答会,那我问你:你意思就是在每一个方法里加入 try...catch...
代码了?
当然,这样并不是不行,是不太好。你想想,这样写起来是不是也太累了,我们都很懒的,而且我们程序里有一个讲究是「耦合性」,那你这就完全不符合「高内聚、低耦合」咯?简单说,异常的处理对业务代码的侵入性太强了,不够美,我们当然有更好的处理方式了。
我们可不可以统一处理异常呢? 当然可以啦!
现在就新建一个ExceptionHandler.java
异常处理类。
@Component
public class ExceptionHandler implements HandlerExceptionResolver {
private static Logger log = Logger.getLogger(ExceptionHandler.class);
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) {
log.error("ExceptionHandler 捕获的异常:", exception);
String requestType = request.getHeader("X-Requested-With");
String type = "api"; //TODO:
if (!type.equals("api") && StrUtil.isNullOrEmpty(requestType)) {
// 非API请求
return new ModelAndView("redirect:/500.html");
} else {// JSON格式返回
Map<String, Object> responseMap = new HashMap<String, Object>();
responseMap.put("code", -1);
responseMap.put("msg", "系统异常,请稍后重试!");
String json = new Gson().toJson(responseMap);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
try {
response.getWriter().write(json);
response.getWriter().flush();
return null;
} catch (IOException e) {
log.error("", e);
}
}
return new ModelAndView("redirect:/500.html");
}
}
好,就这样简单,完成了异常的统一处理。其实是 Spring 中定义的 HandlerExceptionResolver
接口,我们重写里边的 resolveException
方法就可以捕获项目中未处理的异常。当然,这就要求我们项目中的异常要一层一层的抛出去了,这时候不要担心,我们会最终捕获它的。
现在简单说说上边我的捕获代码的处理方式,首先,我捕获到异常就写一个 log 记录它,以便于我们找出查看,然后,如果是我们的 API 接口请求的话,我就返回接口的统一 Json 格式,如果是其他请求的话,我就会返回到一个 500 的错误页面,以优雅的方式提示用户。
怎么使用
其实,完全就不用说怎么使用了,非常简单的用法,mafly.那这里我就试着抛一个异常出去,然后故意不捕获它,看看结果到底会怎样?
1.先在 ServiceImp 层抛一个异常。
2.在 Controller 层调用这个方法。
3.请求一个 API 接口。
这时候,你看控制台打印出来了异常日志,就是我们刚刚抛出来的,你也可以调试一下,看看执行过程。这个时候,你就可以随心所欲的统一处理异常了。
文章的具体的案例,都可以访问我的 Github 看到 https://github.com/mafly/SpringDemo
从零开始学 Java - Spring MVC 统一异常处理的更多相关文章
- 从零开始学 Java - Spring MVC 实现跨域资源 CORS 请求
论职业的重要性 问:为什么所有家长都希望自己的孩子成为公务员? 答:体面.有权.有钱又悠闲. 问:为什么所有家长都希望自己的孩子成为律师或医生? 答:体面.有钱.有技能. 问:为什么所有家长都不怎么知 ...
- 从零开始学 Java - Spring 支持 CORS 请求踩的坑
谁没掉进过几个大坑 记得好久之前,总能时不时在某个地方看到一些标语,往往都是上面一个伟人的头像,然后不管是不是他说的话,下面总是有看起来很政治正确且没卵用的屁话,我活到目前为止,最令我笑的肚子痛得是下 ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)
从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- Spring MVC 统一异常处理
Spring MVC 统一异常处理 看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或 ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)
Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)
你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)
硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
随机推荐
- PHPCMS后台密码忘记解决办法
什么是PHPCMS? PHPCMS是一款网站管理软件.该软件采用模块化开发,支持多种分类方式,使用它可方便实现个性化网站的设计.开发与维护.它支持众多的程序组合,可轻松实现网站平台迁移,并可广泛满足各 ...
- Eclipse启动参数
from 网络 eclipse 启动参数 -clean2013-- : eclipse 启动参数介绍(如添加插件时,如果不显示,则使用eclipse -clean启动) 其实,Eclipse是一个可以 ...
- C#设计模式-代理模式
在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访问到这些对象,如果直接访问对象给系统带来不必要的复杂性,这时候可以在客户端和目标对象之间增加一层中间层,让代理对象代替 ...
- 小谈Java里的线程
今天,我们来谈一谈Java里的线程. 一.进程与线程的基本概念 大家可能没听过线程这个概念,但是相信,用计算机的朋友都听过进程这个概念.打开电脑的任务管理器,我们就可以看到许多进程.它们主要分为三类, ...
- 谈谈service层在mvc框架中的意义和职责
mvc框架由model,view,controller组成,执行流程一般是:在controller访问model获取数据,通过view渲染页面. mvc模式是web开发中的基础模式,采用的是分层设计, ...
- sizzle分析记录:属性选择器
源码部分 通过Sizzle.attr匹配出值 然后通过表达式刷选计算 "ATTR": function( name, operator, check ) { return func ...
- python3 字符串与列表常用功能
一.字符串常用功能 1. capitalize(),将字符串的首字母变成大写,其余全部置为小写:如果字符串中有多个单词,也只是将第一个单词的首字母置为大写:例: >>> name = ...
- Util应用程序框架公共操作类(三):数据类型转换公共操作类(扩展篇)
上一篇以TDD方式介绍了数据类型转换公共操作类的开发,并提供了单元测试和实现代码,本文将演示通过扩展方法来增强公共操作类,以便调用时更加简化. 下面以字符串转换为List<Guid>为例进 ...
- 如何用Perl截取报文
在实际生产环境中,常常需要从后台日志中截取报文,报文的形式类似于 <InterBOSS> ... ... ... </InterBOSS> 一个后台日志有多个报文,每个报文可由 ...
- Cesium应用篇:3控件(2)BaseLayerPicker
所有范例均在github中搜索:ExamplesforCesium BaseLayerPicker控件非常简单,似乎没什么可说的,确实非常的简单,但作为一个底图选择控件,可以说是最基本的一个控件. C ...