`

使用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中的异常处理机制,帮助你更好地理解如何优雅地处理错误和异常。 1. **Spring MVC 异常处理概述** Spring MVC 提供了一种统一的方式来处理应用程序中抛出的异常。它通过`@...

    spring mvc异常简单处理

    此外,Spring MVC还支持使用`HandlerExceptionResolver`接口来自定义异常解析器。实现这个接口并将其注册到Spring的bean容器中,我们就可以完全控制异常的处理流程,包括决定何时返回错误页面,何时返回JSON响应,...

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

    本篇文章将详细探讨Spring MVC处理异常的三种主要方法:SimpleMappingExceptionResolver、自定义HandlerExceptionResolver以及@ExceptionHandler注解。 1. SimpleMappingExceptionResolver Spring MVC提供了内置的...

    spring mvc 参数绑定漏洞

    1. **类型转换异常处理**:通过自定义`HandlerExceptionResolver`或使用全局异常处理器(`@ControllerAdvice`),捕获并处理类型转换异常,避免向用户透露过多敏感信息。 2. **输入验证**:使用注解(如`@...

    spring mvc 事务配置+异常处理

    Spring MVC提供了多种方式来处理异常,包括传统的Java异常捕获机制、自定义异常处理器和使用`@ExceptionHandler`注解。 - **传统异常捕获**:通过在Controller方法内部使用try-catch语句来捕获和处理异常。 - **...

    第11章Spring MVC常用参数的使用可运行源码 Spring MVC简单应用

    在本章中,我们将深入探讨 Spring MVC 的常用参数及其使用,通过可运行的源码来实践和理解这些概念。 1. **Spring MVC 概述** Spring MVC 提供了一个模型-视图-控制器架构,用于解耦应用程序的业务逻辑、数据处理...

    Spring MVC示例

    Spring MVC提供了统一的异常处理机制,可以使用`@ExceptionHandler`注解在Controller方法中处理特定异常,或者全局地配置`HandlerExceptionResolver`。 综上所述,这个"Spring MVC示例"项目是一个完整的Web应用...

    【Michelle.Chung】spring mvc demo - HandlerExceptionResolver

    【Spring MVC】Filter 过滤器异常处理 HandlerExceptionResolver 分析 demo

    Spring.MVC学习指南.pdf

    - 全局异常处理可以通过实现HandlerExceptionResolver接口或使用@ControllerAdvice和`@ExceptionHandler`注解来实现。 7. **RESTful API设计**: - 利用HTTP动词(GET, POST, PUT, DELETE等)和URI资源路径来设计...

    Spring MVC 配套资料

    6. HandlerExceptionResolver:异常处理器,处理 Controller 执行过程中抛出的异常。 三、Spring MVC 工作流程 1. 用户发送 HTTP 请求到 DispatcherServlet。 2. DispatcherServlet 根据请求信息找到相应的 ...

    spring mvc rest基础学习demo

    - 可以通过`@ExceptionHandler`注解处理特定类型的异常,或者全局异常处理器类实现`HandlerExceptionResolver`接口。 7. **测试** - 使用`MockMvc`进行单元测试和集成测试,模拟HTTP请求并验证响应。 8. **...

    Spring MVC总结.doc

    Spring MVC提供了统一的异常处理机制,可以通过配置`HandlerExceptionResolver`来捕获和处理异常,增强了应用的健壮性。 9. **测试支持** Spring MVC为单元测试和集成测试提供了强大的支持,可以通过MockMVC API...

    Spring MVC的总结梳理

    - **HandlerExceptionResolver**接口:用于处理处理器抛出的异常。 - **SimpleMappingExceptionResolver**实现类:提供了一种基于配置文件的异常处理机制。 - **HandlerMapping**接口及其实现类:负责将请求映射到...

    spring-mvc学习文档资料

    Spring MVC 提供了多种异常处理方式,如 @ExceptionHandler 注解、HandlerExceptionResolver 等。ExceptionHandler 负责捕获异常并将其返回给客户端。 安全 Spring MVC 提供了多种安全机制,如权限控制、身份验证...

    Spring MVC+EXT JS开发简单的增删改查入门实例

    - 故障排查:使用Spring MVC的HandlerExceptionResolver处理异常,EXT JS的错误处理机制捕捉前端错误。 **六、总结** 通过整合Spring MVC和EXT JS,我们可以构建出既具有强大功能又具有良好用户体验的Web应用。理解...

    Spring MVC 中文资料

    9. **`HandlerExceptionResolver` 接口及其实现类**:如 `SimpleMappingExceptionResolver`,用于处理异常。 10. **`ModelAndView` 类**:用于封装模型数据和视图信息。 #### 三、核心流程分析 Spring MVC 的...

    Spring mvc入门Demo资料

    - 全局异常处理器可以通过实现`HandlerExceptionResolver`接口或使用`@ControllerAdvice`注解来创建。 8. **验证** - Spring MVC提供了一套验证机制,如`@Valid`注解配合JSR-303/JSR-349 Bean Validation进行数据...

    spring mvc 简单例子

    Spring MVC 提供了 @ExceptionHandler 注解,可以在 Controller 中捕获特定的异常并进行处理。此外,全局异常处理可以通过配置 HandlerExceptionResolver 来实现。 9. **验证** Spring MVC 集成了 Bean ...

    Spring MVC异常处理机制示例详解

    HandlerExceptionResolver 接口是 Spring MVC 异常处理机制的核心接口,该接口只有一个处理方法,即 resolveException 方法,该方法将请求、响应、处理器和异常作为参数,并返回一个 ModelAndView 对象。对于返回值 ...

Global site tag (gtag.js) - Google Analytics