2014-09-29 182 views
0

我正在使用以下泛型类来处理我的应用程序中的所有类型的异常。它处理大多数异常,但对于某些例如“org.apache.tiles.impl.CannotRenderException”失败。我怎样才能使它捕获所有类型的异常?Spring MVC通用异常处理

一些,我使用的技术是:春季4.0.0.RELEASE,瓷砖2.2,Maven的1.6,春天的Webflow 2.4.0.RELEAS

@ControllerAdvice 
class GenericDefaultExceptionHandler { 
    public static final String DEFAULT_ERROR_VIEW = "error/error"; 
    private static final String DEFAULT_ERROR_SUBJECT = "Exception occurred"; 
    final Logger logger = LoggerFactory.getLogger(getClass()); 

    @Autowired 
    private MailService mailService; 

    @ExceptionHandler(value = Exception.class) 
    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception { 
     if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) 
      throw e; 
     ModelAndView mav = new ModelAndView(); 
     mav.addObject("exception", e); 
     mav.addObject("url", req.getRequestURL()); 
     mav.setViewName(DEFAULT_ERROR_VIEW); 
     //send email to system admin 
     sendMessageToAdmin(e.toString(),req.getRequestURL().toString()); 
     logger.error(e.toString()); 
     return mav; 
    } 

    private void sendMessageToAdmin(String exceptionAsMessage, String url) { 
     try { 
      StringBuilder errorMessage = new StringBuilder(); 
      errorMessage.append("Exception on request URL :"); 
      errorMessage.append(url); 
      errorMessage.append("\n\n"); 
      errorMessage.append("The Exception was: "); 
      errorMessage.append(exceptionAsMessage); 
      mailService.sendMailWithSubject(DEFAULT_ERROR_SUBJECT,errorMessage.toString()); 
     } catch (Exception e) { 

     } 
    } 
} 

感谢

回答

1

的问题是,您的处理程序捕获控制器中的异常,但在控制器完成其作业后,视图中会抛出异常。您可以尝试使用一个过滤器来处理它们:

public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 
    ... 
    try { 
     chain.doFilter(request, response); 
    } 
    catch (Exception ex) { 
     // your stuff 
     ... 
     throw new ServletException(ex); 
    } 
} 

Independantly的那个(或补充),你也可以要求容器使用一些看法时,发现异常时,或者当控制器使用sendError在一些配置web.xml文件:

<!-- error-code related error pages --> 
<error-page> 
    <error-code>404</error-code> 
    <location>/ErrorHandler</location> 
</error-page> 
<error-page> 
    <error-code>403</error-code> 
    <location>/ErrorHandler</location> 
</error-page> 

<!-- exception-type related error pages --> 
<error-page> 
    <exception-type> 
      javax.servlet.ServletException 
    </exception-type > 
    <location>/ErrorHandler</location> 
</error-page> 

<error-page> 
    <exception-type>java.io.IOException</exception-type > 
    <location>/ErrorHandler</location> 
</error-page> 
+0

过滤器是确定的方式。我们的异常过滤器通过电子邮件发送我们网站中发生的所有异常,并向电子邮件添加有趣的元数据:会话ID,远程地址,用户代理等......但是我们也列出了一些异常,例如套接字异常,每天的时间,而且毫无意义。 – hooknc 2014-09-29 21:37:11

0

是的,过滤器为我工作。我创建了一个扩展Spring过滤器的GenericFilterBean的异常类,并将其注册到我的ApplicationConfig中。

public class ApplicationConfig implements WebApplicationInitializer { 
    ..... 
    @Override 
    public void onStartup(ServletContext servletContext) throws ServletException { 
     ..... 
     FilterRegistration.Dynamic exception = servletContext.addFilter("genericExceptionFilter", new GenericExceptionFilter()); 
     exception.addMappingForUrlPatterns(dispatcherTypes, true, "/*"); 
     ..... 
    } 
} 

谢谢。