Spring MVC 统一异常处理
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 统一异常处理的更多相关文章
- 使用Spring MVC统一异常处理实战
		
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
 - 使用Spring MVC统一异常处理实战<转>
		
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
 - 使用Spring MVC统一异常处理实战(转载)
		
原文地址:http://blog.csdn.net/ufo2910628/article/details/40399539 种方式: (1)使用Spring MVC提供的简单异常处理器SimpleMa ...
 - Spring MVC统一异常处理
		
实际上Spring MVC处理异常有3种方式: (1)一种是在Controller类内部使用@ExceptionHandler使用注解实现异常处理: 可以在Controller内部实现更个性化点异常处 ...
 - spring MVC 统一异常处理(webapi和web分开处理)
		
转载: http://blog.csdn.net/m13321169565/article/details/7641978 http://blog.csdn.net/ethan_fu/article/ ...
 - 从零开始学 Java - Spring MVC 统一异常处理
		
看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或者你已经练功到了孤独求败,等了半辈子 ...
 - 【转】使用Spring MVC统一异常处理实战
		
方法一:使用SimpleMappingExceptionResolver实现异常处理 //在Spring的配置文件applicationContext.xml中增加以下内容: <bean cla ...
 - spring mvc统一异常处理(@ControllerAdvice + @ExceptionHandler)
		
spring 封装了非常强大的异常处理机制.本文选取@ControllerAdvice + @ExceptionHandler 这种零配置(全注解),作为异常处理解决方案! @ControllerAd ...
 - 使用Spring MVC统一异常处理
		
http://blog.csdn.net/ufo2910628/article/details/40399539
 
随机推荐
- ViewPager中使用自定义的ListView实例
			
这篇内容是上一篇的延续,因为在上一篇的测试ViewPager成功了,才能实现这一篇的和ListView合在一起使用 效果图如下: 不愿意说理论,直接上代码 1.清单文件 activity_main.x ...
 - 使用Java辅助类(CountDownLatch、CyclicBarrier、Semaphore)并发编程
			
在java 1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下这三个辅助类的用法 一.C ...
 - android开发布局优化之ViewStub
			
使用ViewStub可以延迟加载一个布局文件,提高显示速率.刚开始接触到,记录下来. 关于viewstub的使用,我们可以在不同的布局中使用,比如可以根据设备的大小动态决定显示哪个界面. viewst ...
 - Android界面的View以及ViewGroup的区别
			
因为这个问题会经常成为面试的热点,所以我们来谈谈View以及ViewGroup的区别. 先看看View及ViewGroup类关系 Android View和ViewGroup从组成架构上看,似乎 ...
 - radio的change事件
			
radio的change事件 <scripttype="text/javascript"> $(document).ready(function(){ $(" ...
 - jquery插件下载地址
			
以下是本人收集的jquery插件下载地址: .............版本自行选择. jquery官网:http://jquery.com/ jquery.validate.js 官网下载地址:htt ...
 - React+Immutable.js的心路历程
			
这段时间做的项目开发中用的是React+Redux+ImmutableJs+Es6开发,总结了immutable.js的相关使用姿势: Immutable Data 顾名思义是指一旦被创造后,就不可以 ...
 - 在自定义的web监听器中嵌入web中的定时事件
			
在 http://www.cnblogs.com/myadmin/p/4806265.html 中说明了自定义web监听器的一些东西. 本文中的web定时任务也基于上篇文章的自定义web监听器. 新建 ...
 - js 配置基础启动文件
			
页面启动文件boot.js,获取存放该文件的路径,放置通用的css,js代码,方便html页面调用. __CreateJSPath = function (js) { var scripts = do ...
 - .NET设计模式(4):建造者模式(Builder Pattern)
			
):建造者模式(Builder Pattern) .建造者模式的使用使得产品的内部表象可以独立的变化.使用建造者模式可以使客户端不必知道产品内部组成的细节. 2.每一个Builder都相对独立, ...