2011-02-23 83 views
8

ive在我的spring 2.5应用程序中设置了一个简单的异常处理程序。目前它捕获所有Exception s并显示堆栈跟踪页面。春天异常处理程序不处理某些类型的异常

这是很好,但现在Spring Security没有正确地踢了非登录用户的登录页面,而不是我的异常,显示的网页春季安全异常:

org.springframework.security.AccessDeniedException 

问题是这个应用程序没有自己的异常子类,它使用它的所有例外,所以我必须映射Exception但unmap AccessDeniedException

这是可能的春天2.5?

编辑:弹簧安全2.0.1

我的豆看起来像这样

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
    <property name="exceptionMappings"> 
     <props> 
      <prop key="java.lang.RuntimeException">common/error</prop> 
     </props> 
    </property> 
</bean>** 
+0

不知道,但我也对解决方案感兴趣。 – Kartoch 2011-02-23 17:28:27

+0

您使用的是哪种版本的spring security? – Ritesh 2011-02-25 17:52:37

+0

spring security 2.0.1 – mkoryak 2011-02-25 20:16:29

回答

4

我们处理这个问题的方式是拥有一个自定义的异常解析器类,该类处理任何未被其他处理器捕获的异常 - 它实现HandlerExceptionResolver,Ordered。

我们声明了一个单独的SimpleMappingExceptionResolver bean,它捕获特定的异常。

排序是这样的,我们的自定义解析器在SimpleMappingExceptionResolver之后运行。

其结果是指定的异常(例如AccessDeniedException)由SimpleMappingExceptionResolver处理,并指向适当的页面。

任何其他运行时异常都由自定义解析器处理,该自定义解析器转发到通用错误页面。

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
    <property name="exceptionMappings"> 
     <props> 
      <prop key="org.springframework.security.AccessDeniedException">accessDenied</prop> 
      <prop key="org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException">accessDenied</prop> 
     </props> 
    </property> 
    <property name="order" value="0"/> 
</bean> 

<bean class="package.to.your.handler.DefaultExceptionResolver"> 
    <property name="order" value="1"/> 
</bean> 

这种安排可以让你捕捉尽可能多的例外,只要你喜欢(我在这里赶上2,存取遭拒和HibernateOptimisticLockingFailureException)使用Spring解析器和其他一切由自定义解析器抓获。在上面接受的解决方案中,您将不得不编写更多的Java代码来捕获除AccessDenied以外的异常。

+0

你刚才说的是接受的解决方案中完全相同的东西,除了较少的细节:P – mkoryak 2011-04-28 17:31:26

+0

更多的细节编辑到我的答案。 – SteveT 2011-04-29 01:10:01

+0

啊谢谢你 – mkoryak 2011-04-29 02:48:12

0

看来SimpleMappingExceptionHandler有一个属性MappedHandlerClasses这就是你要找的东西,因为它可以接受一组例外。

+0

你确定,从doc似乎该字段需要处理映射的异常的'Handler'对象列表 – mkoryak 2011-02-23 17:52:09

2

建立在Kartoch的答案上,在你的映射中你有几个选项。您可以更具体地指定要捕获的异常,而不是RuntimeException,或者,您可以为AccessDeniedExcpetion指定处理程序的登录视图。像重定向:/ login?err = 401作为视图名称。

见的配置在这里完成

http://www.mkyong.com/spring-mvc/spring-mvc-exception-handling-example/

在那里他与一个豆处理多个异常。你会做同样的并重定向到你的登录视图。唯一悬而未决的问题是,如果它在配置中接受重定向:/ viewname,并且我现在无法测试它。处理这种

+0

我不能更具体,因为我继承的应用程序已经抛出了RunTimeException all在这个地方,我不能去改变它在一百万个地方 – mkoryak 2011-02-25 20:15:49

+0

对,我想到了很多,这就是为什么我包括第二个选项。 – digitaljoel 2011-02-25 20:19:11

7

一种方法是创建另一个处理程序执行org.springframework.web.servlet.HandlerExceptionResolverorg.springframework.core.Orderedγ-接口。在自己的实现,你这样做了以下内容:

public class AccessDeniedExceptionResolver implements HandlerExceptionResolver, Ordered 
{ 
    private int order; 

    @Override 
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) 
    { 
     if(exception instanceof AccessDeniedException) 
     { 
      return new ModelAndView("redirect:/login"); //Replace with redirect to your login-page 
     } 

     return null; //Null-return = pass the exception to next handler in order 
    } 

    public void setOrder(int order) 
    { 
     this.order = order; 
    } 

    @Override 
    public int getOrder() 
    { 
     return order; 
    } 
} 

现在,有序的接口实现允许你告诉异常处理程序在调用的顺序的SimpleMappingExceptionResolver也实现了Ordered接口,所以你可以不喜欢在你的bean,定义如下:

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> 
    <property name="exceptionMappings"> 
     <props> 
      <prop key="java.lang.RuntimeException">common/error</prop> 
     </props> 
    </property> 
    <property name="order" value="1"/> 
</bean> 

<bean class="package.to.your.handler.AccessDeniedExceptionResolver"> 
    <property name="order" value="0"/> 
</bean> 

与下订单值的bean具有更高的优先级(这意味着它将与较大值的问题之前被调用,在这种情况下AccessDeniedExceptionResolver之前调用SimpleMappingEx ceptionResolver。

希望这有助于。

+0

感谢这个作品..我必须等待20个小时给你的观点。 – mkoryak 2011-02-25 21:02:07

+0

将SimpleMappingExceptionResolver中的另一个添加到映射到重定向:/ login的AccessDeniedException中,而不是必须实现一个类来执行此操作吗? – digitaljoel 2011-02-25 21:15:14

+0

@mkoryak:谢谢,不急。在此之前,还可能会出现一个更好的解决方案,如果发生这种情况,不会有任何困难的感觉;)另外,请看看在这里建议的digitaljoel。 – esaj 2011-02-26 10:09:17

1

还有一种选择:创建一个SimpleMappingExceptionResolver的子类,它能够排除某些异常类(将它们保留为默认处理,在您的情况下为Spring Security)。

public class ExclusionExceptionResolver extends SimpleMappingExceptionResolver implements InitializingBean { 
    private Class[] excludedClasses; 

    @Override 
    protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { 
    for (Class<?> excludedClass : excludedClasses) { 
     if (excludedClass.isInstance(ex)) { 
     return null; 
     } 
    } 
    return super.doResolveException(request, response, handler, ex); 
    } 
    public void setExcludedClasses(Class[] excludedClasses) { 
    this.excludedClasses = excludedClasses; 
    } 

    @Override 
    public void afterPropertiesSet() throws Exception { 
    if (excludedClasses == null) { 
     excludedClasses = new Class[]{}; 
    } 
    } 
}