2011-02-23 82 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[]{}; 
    } 
    } 
}