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

Spring MVC 统一异常处理的更多相关文章

  1. 使用Spring MVC统一异常处理实战

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

  2. 使用Spring MVC统一异常处理实战<转>

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

  3. 使用Spring MVC统一异常处理实战(转载)

    原文地址:http://blog.csdn.net/ufo2910628/article/details/40399539 种方式: (1)使用Spring MVC提供的简单异常处理器SimpleMa ...

  4. Spring MVC统一异常处理

    实际上Spring MVC处理异常有3种方式: (1)一种是在Controller类内部使用@ExceptionHandler使用注解实现异常处理: 可以在Controller内部实现更个性化点异常处 ...

  5. spring MVC 统一异常处理(webapi和web分开处理)

    转载: http://blog.csdn.net/m13321169565/article/details/7641978 http://blog.csdn.net/ethan_fu/article/ ...

  6. 从零开始学 Java - Spring MVC 统一异常处理

    看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或者你已经练功到了孤独求败,等了半辈子 ...

  7. 【转】使用Spring MVC统一异常处理实战

    方法一:使用SimpleMappingExceptionResolver实现异常处理 //在Spring的配置文件applicationContext.xml中增加以下内容: <bean cla ...

  8. spring mvc统一异常处理(@ControllerAdvice + @ExceptionHandler)

    spring 封装了非常强大的异常处理机制.本文选取@ControllerAdvice + @ExceptionHandler 这种零配置(全注解),作为异常处理解决方案! @ControllerAd ...

  9. 使用Spring MVC统一异常处理

    http://blog.csdn.net/ufo2910628/article/details/40399539

随机推荐

  1. Linux下l2tp客户端xl2tpd的安装配置

    1.下载xl2tp http://pkgs.org/search/?query=xl2tp&type=smart选择相应的版本进行下载 2.安装xl2tp和ppp yum install xl ...

  2. gitbook 制作 beego 参考手册

    安装gitbook工具 npm install -g gitbook-cli 从github 下载beego文档 https://github.com/beego/beedoc 创建目录 在 zh-c ...

  3. 【转】Cannot change version of project facet Dynamic Web Module to 3.1 (Eclipse Maven唯一解决方案)

    If you want to use version 3.1 you need to use the following schema: http://xmlns.jcp.org/xml/ns/jav ...

  4. 用C#实现通用守护进程

    1. 下载 源码下载:http://pan.baidu.com/s/1vqDA2 安装包下载:http://pan.baidu.com/s/1sjmEB0p 2. 安装注意事项 在配置档中配置你要守护 ...

  5. iOS开发大神必备的Xcode插件

    写在前面 工欲善其事,必先利其器,iOS开发中不仅要学会Xcode的基本操作,而且还得学会一些Xcode的使用技巧,如掌握常用的快捷键等,还有就是今天要说到的Xcode插件,下面我就为大家介绍几款开发 ...

  6. android开发之记录ListView滚动位置

    这个问题本身不难,但是由于项目中的需求太过于复杂,结果导致这个问题变得不是那么容易实现.在网上一搜,结果如下: 我不知道是who copy who?反正介绍的所谓的三种方法,第一种都是无法运行的,很明 ...

  7. Java基础知识强化之集合框架笔记57:Map集合之HashMap集合(HashMap<Student,String>)的案例

    1. HashMap集合(HashMap<Student,String>)的案例 HashMap<Student,String>键:Student      要求:如果两个对象 ...

  8. Java基础知识强化之IO流笔记25:FileInputStream / FileOutputStream 复制图片案例

    1.  需求:把D:\\美女.jpg 复制到当前项目目录下mn.jpg 代码示例: package com.himi.filecopy; import java.io.FileInputStream; ...

  9. Linux终端Ctrl相关快捷键

    快速跳至行首:Ctrl+A 快速跳至行尾:Ctrl+E 向前删除至行首:Ctrl+U 向后删除至行尾:Ctrl+K 向后删一个单词:Ctrl+D 清屏:Crtl+L(clear)

  10. Effective C++ 笔记二 构造/析构/赋值运算

    条款05:了解C++默默编写并调用哪些函数 编译器默认声明一个default构造函数.一个copy构造函数.一个copy assignment操作符和一个析构函数.这些函数都是public且inlin ...