spring异常处理程序不处理某些类型的异常

mko*_*yak 8 exception-handling spring-mvc spring-security

我在我的Spring 2.5应用程序中设置了一个简单的异常处理程序.目前它捕获所有Exceptions并显示堆栈跟踪页面.

这很好,但是现在Spring安全性没有正确地将未登录的用户踢到登录页面,而是显示了弹出安全性异常的异常页面:

org.springframework.security.AccessDeniedException
Run Code Online (Sandbox Code Playgroud)

问题是这个应用程序没有自己的Exception子类,它用于它的所有Exceptions,所以我必须映射Exception但是unmapAccessDeniedException

这可能在春季2.5?

编辑:使用spring security 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>**
Run Code Online (Sandbox Code Playgroud)

esa*_*saj 7

处理此问题的一种方法是创建另一个实现org.springframework.web.servlet.HandlerExceptionResolverorg.springframework.core.Ordered -interfaces的处理程序 .在您自己的实现中,您执行以下操作:

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;
    }   
}
Run Code Online (Sandbox Code Playgroud)

现在,Ordered接口实现允许您告诉调用异常处理程序的顺序.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>
Run Code Online (Sandbox Code Playgroud)

具有LOWER order-value的bean具有更高的优先级(意味着它将在具有更大值的bean之前被调用,在这种情况下,在SimpleMappingExceptionResolver之前调用AccessDeniedExceptionResolver.

希望这有帮助.


Ste*_*veT 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>
Run Code Online (Sandbox Code Playgroud)

这种安排允许您使用 Spring 解析器捕获任意数量的异常(我在这里捕获 2 个,AccessDenied 和 HibernateOptimisticLockingFailureException),而其他所有异常都由自定义解析器捕获。在上面接受的解决方案中,您必须编写更多 Java 代码来捕获除 AccessDenied 之外的异常。