`

使用Spring MVC HandlerExceptionResolver处理异常

阅读更多
转载请标明出处:http://fuliang.iteye.com/blog/947191

Spring MVC的确很强大,在每一个你想的到和想不到的地方都会留下钩子,来插入自定义的实现,透明替换默认实现,
拦截器堆栈结构设计的非常强大,多种试图的解析,url mapping的多种实现,Locale resolver、Theme resolver
、multipart file resolver,Excepiton hanlder Resolver等等,能让Spring MVC从1.0到3.0经历巨大变化,
仍能向后兼容,并支持很酷的RESTful风格和强大的简化xml配置的注解。
这些功能我们在项目中经常用到,但是Excepiton hanlder Resolver可能是个生僻一点的东东,因为我们通常对错误
的处理通常不是非常的复杂,很多情况下只是根据异常或者http error code跳转到错误页面,这个是JSP/servlet就可
以搞定,在web.xml配置一下即可。

今天遇到一个事情,让我想用到HandlerExceptionResolver这个东东来处理异常。今天准备把自助系统进入上线状态,
所以把log的级别从DEBUG调到INFO,结果没有catch的Runtime异常在log记录,后来跟踪了一下原来Spring把异常处理的log,
直接使用的是debug,而不是error,所以log级别设置为INFO导致异常没有记录,看了一下spring的源代码:
// Check registerer HandlerExceptionResolvers...
ModelAndView exMv = null;
for (Iterator it = this.handlerExceptionResolvers.iterator(); exMv == null && it.hasNext();) {
HandlerExceptionResolver resolver = (HandlerExceptionResolver) it.next();
exMv = resolver.resolveException(request, response, handler, ex);
}
if (exMv != null) {
if (logger.isDebugEnabled()) {
logger.debug("Handler execution resulted in exception - forwarding to resolved error view: " + exMv, ex);
}
WebUtils.exposeErrorRequestAttributes(request, ex, getServletName());
return exMv;
}

可以看到可以插入自己的HandlerExceptionResover来搞定这个问题,我们可以在resolveException方法任意处理异常和log。也可以
把错误信息个性化后传到view层显示。
我们只有简单的需求,就是把没有catch的异常记入log,将异常的完整信息放在错误页面的一个隐藏的区域,方便查找出现错误的原因。
首先我们实现HandlerExceptionResolver
package com.qunar.advertisement.exception;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.qunar.advertisement.utils.StringPrintWriter;

public class QADHandlerExceptionResolver implements HandlerExceptionResolver{
    private static Logger logger = Logger.getLogger(QADHandlerExceptionResolver.class);
    @Override
    public ModelAndView resolveException(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {
        logger.error("Catch Exception: ",ex);//把漏网的异常信息记入日志
        Map<String,Object> map = new HashMap<String,Object>();
        StringPrintWriter strintPrintWriter = new StringPrintWriter();
        ex.printStackTrace(strintPrintWriter);
        map.put("errorMsg", strintPrintWriter.getString());//将错误信息传递给view
        return new ModelAndView("error",map);
    }

}

我们还需要一个辅助的类StringPrintWriter,因为ex.printStackTrace参数只有个PrintWriter类型的,java自带的StringWriter
不可用,所以我们需要自己实现一个装饰器的StringPrintWriter。
package com.qunar.advertisement.utils;

import java.io.PrintWriter;
import java.io.StringWriter;

public class StringPrintWriter extends PrintWriter{

    public StringPrintWriter(){
        super(new StringWriter());
    }
   
    public StringPrintWriter(int initialSize) {
          super(new StringWriter(initialSize));
    }
   
    public String getString() {
          flush();
          return ((StringWriter) this.out).toString();
    }
   
    @Override
    public String toString() {
        return getString();
    }
}

我们只需要在xml中配置一下就可以了:
<bean class="com.qunar.advertisement.exception.QADHandlerExceptionResolver">
</bean>

我们在错误页面隐藏区域显示错误信息:
<div style="display:none;">
     <c:out value="${errorMsg}"></c:out>
</div>
分享到:
评论
13 楼 bing_it 2015-11-05  
12 楼 dsjt 2015-04-08  
楼主spring 什么版本,
我的3.1 ,xml中配置 <bean class="com.qunar.advertisement.exception.QADHandlerExceptionResolver"> 
</bean> 

无效,spring 还是用自带的ExceptionHandlerExceptionResolver 来处理异常。
11 楼 在世界的中心呼喚愛 2015-04-06  
这样是可以。。
不过异常在前端要转义下。
不然用户看异常信息有什么用?
10 楼 120153216 2014-11-06  
<br/>
9 楼 120153216 2014-11-06  
        /
8 楼 120153216 2014-11-06  
7 楼 zhangbd_Answer 2013-12-30  
必须用在spring mvc 里面吗,我项目框架式ssi,可以吗?
6 楼 hash 2013-08-19  
要是返回json 直接返回一个json对象给前台
PrintWriter writer = response.getWriter();
String json="{\"success\":false,\"msg\":\""+ex.getMessage()+"\"}";
writer.write(json);
writer.flush();
5 楼 ysa198584 2013-02-06  
"返回json的view 而不是页面",怎么返回了,不是要"
return new ModelAndView(redirectUrl),这样写吗
"
4 楼 tanjianna 2013-01-07  
fuliang 写道
可以,出错可以QADHandlerExceptionResolver 中返回json的view 而不是页面

謝謝!
3 楼 fuliang 2012-12-21  
可以,出错可以QADHandlerExceptionResolver 中返回json的view 而不是页面
2 楼 tanjianna 2012-12-11  
如果 我不想跳转到另一个页面显示呢?我想直接用json获取?可以吗?
因为 我在action类里面 直接返回json的!能有解决方法吗?
1 楼 Waht 2012-08-22  

    [*]
[url][/url][flash=200,200][/flash]
[b][/b][url][/url]     

相关推荐

    spring mvc统一处理异常

    spring mvc统一处理异常,通过@ControllerAdvice+@ExceptionHandler

    spring mvc异常处理

    spring mvc异常处理,详细参考http://blog.csdn.net/xiejx618/article/details/41918611

    精通Spring MVC 4

    本书共计10章,分别介绍了快速搭建Spring Web应用、精通MVC结构、URL映射、文件上传与错误处理、创建Restful应用、保护应用、单元测试与验收测试、优化请求、将Web应用部署到云等内容,循序渐进地讲解了Spring MVC4...

    springmvc 异常统一处理的三种方式详解.docx

    在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理...下面将介绍使用Spring MVC统一处理异常的解决和实现过程。

    Spring MVC入门教程

    十一、spring mvc 如何实现全局的异常处理? 十二、spring mvc 如何把全局异常记录到日志中? 十三、如何给spring3 MVC中的Action做JUnit单元测试? 十四、spring mvc 转发与重定向 十五、spring mvc 处理ajax请求 ...

    Spring MVC 教程 快速入门 深入分析

    十一、spring mvc 如何实现全局的异常处理? 十二、spring mvc 如何把全局异常记录到日志中? 十三、如何给spring3 MVC中的Action做JUnit单元测试? 十四、spring mvc 转发与重定向 十五、spring mvc 处理ajax请求 ...

    spring mvc 官方文档

    本文详细介绍spring MVC的原理和开发心得体会。

    SpringMVCDemo:Spring MVC 框架知识案例

    1.创建第一个 Spring MVC 程序案例 2.Spring MVC @RequestMapping 注解案例 3.Spring MVC 请求参数的获取案例 4.Spring MVC 域对象共享数据案例 5.Spring MVC @ModelAttribute 注解案例 ...15.Spring MVC 异常处理案例

    Spring MVC + Mybatis+Spring实现的个人博客系统

    Spring MVC + Mybatis+Spring实现的个人博客系统基于SSM实现的个人博客系统.zip

    Spring MVC+MyBatis开发从入门到项目实战

    第3篇是Spring MVC技术入门,包括Spring MVC的背景介绍、架构整体剖析、环境搭建、处理器与映射器的讲解、前端控制器的源码分析、多种视图解析器的介绍、请求映射与参数绑定的介绍、Validation校验与异常处理和拦截...

    精通Spring MVC 4 中文

    精通Spring MVC 4 中文

    大优惠 Spring MVC学习指南(第2版)2017.pdf

    Spring MVC是Spring框架中用于Web应用快速开发的一个模块,其中的MVC是Model-View-...本书是一本Spring MVC的教程,内容细致、讲解清晰,非常适合Web开发者和想要使用Spring MVC开发基于Java的Web应用的读者阅读

    Spring MVC 基于注解实例

    Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于注解实例Spring MVC 基于...

    Spring+Spring mvc+Hibernate+Bootstrap、企业级员工信息管理系统

    01. 采用后台及前台的 Spring + ... 通过自定义处理器 ExceptionIntercept 实现 Spring mvc的全局异常捕获 10. 系统中包含了企业中采用的开发工具类的集合 11. AbstractDao 父类实现了Dao中针对单个对象的常用操作

    Spring MVC 入门实例

    这篇文章将教你快速地上手使用 Spring 框架. 如果你手上有一本《Spring in Action》, 那么你最好从第三部分"Spring 在 Web 层的应用--建立 Web 层"开始看, 否则那将是一场恶梦! 首先, 我需要在你心里建立起 Spring...

    [免费]Spring MVC学习指南(高清)

    Spring MVC是Spring框架中用于Web应用快速开发的一个模块,其中的MVC是Model-View-Controller的缩写。作为当今业界最主流的Web开发框架,Spring MVC已经成为当前最热门的开发技能,同时也广泛用于桌面开发领域。 ...

    Spring MVC所需jar包

    Spring MVC所需jar包,包含java开发中 Spring MVC架构中最常用的jar包

Global site tag (gtag.js) - Google Analytics