2011-02-23 3 views
8

필자는 2.5 Spring app에서 간단한 예외 처리기를 설정했습니다. 현재는 Exception 모두를 포착하고 스택 추적 페이지를 보여줍니다.스프링 예외 처리기가 특정 유형의 예외를 처리하지 않습니다.

이 잘 좋은,하지만 지금은 보안 봄 제대로 걷어하지 않는 비 기록 대신 내 예외 페이지는 봄 보안 예외로 표시되며, 로그인 페이지로 사용자의 :

org.springframework.security.AccessDeniedException 

문제 이 응용 프로그램은 모든 예외에 사용되는 자체 Exception 하위 클래스가 없기 때문에 매핑해야합니다. Exception하지만 맵핑을 해제해야합니다. AccessDeniedException

은 스프링 2.5에서 가능합니까?

편집 : 봄 보안 내 콩 SimpleMappingExceptionHandler 당신이,에 관해서는 그것은 할 수 있습니다 무엇을 찾고있어 어떤 속성 MappedHandlerClasses을 가지고 있다는 것이

<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

+0

스프링 보안 버전을 사용하고 있습니까? – Ritesh

+0

스프링 보안 2.0.1 – mkoryak

답변

4

우리가 처리하는 방식은 다른 처리기에서 catch하지 않는 예외를 처리하는 사용자 정의 예외 해결 프로그램 클래스를 가지는 것입니다.이 클래스는 HandlerExceptionResolver, Ordered를 구현합니다.

특정 예외를 포착하는 별도의 SimpleMappingExceptionResolver 빈을 선언합니다.

순서 지정은 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> 

이 배열은 당신이 좋아하는 봄 해결을 사용하여 (내가 여기, AccessDenied 및 HibernateOptimisticLockingFailureException 2를 잡기)와 다른 모든 것이 사용자 지정 해결에 의해 잡힌 당신이 많은 예외를 포착 할 수 있습니다. 위의 허용 된 솔루션에서 AccessDenied 이외의 예외를 잡기 위해 더 많은 Java 코드를 작성해야합니다.

+0

당신은 방금 언급 한 것과 똑같은 해결책을 말했습니다 : 세부 사항은 제외하고 : – mkoryak

+0

자세한 내용은 내 답변에 편집되어 있습니다. – SteveT

+0

아 그 덕분에 – mkoryak

0

처럼 보인다 2.0.1

예외 집합을 허용합니다.

+0

당신은 분명히 필드에서 매핑 된 예외를 처리 할'Handler' 객체의 목록을 취하는 것 같습니다. – mkoryak

2

Kartoch의 답변을 바탕으로 매핑에 몇 가지 옵션이 있습니다. 당신은 RuntimeException 대신 잡으려는 예외에 좀 더 구체적 일 수도 있고 AccessDeniedExcpetion에 대한 핸들러의 로그인 뷰를 지정할 수도 있습니다. 리디렉션과 같은 것 :보기 이름에 대해/login? err = 401.

그가 한 콩으로 취급 여러 예외가 어디 구성이 여기

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

일을 참조하십시오. 동일한 작업을 수행하고 로그인보기로 리디렉션합니다. 유일하게 열려있는 질문은 구성에서/viewname을 리디렉션하는 경우입니다. 지금 당장 테스트 할 수있는 위치에 없습니다. 이 처리하는

+0

상속받은 응용 프로그램이 이미 RunTimeException을 throw하기 때문에 더 구체적이지 않습니다. 모두 그 곳을 돌아 다니면서 만회에서 그것을 바꿀 수있다. – mkoryak

+0

맞아, 나는 그만큼 생각했다. 그래서 나는 두 번째 옵션을 포함시켰다. – digitaljoel

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; 
    } 
} 

의 정렬 된 인터페이스 구현을 사용하면 예외 핸들러에서 호출되는 순서를 알 수 있습니다을 아마도 SimpleMappingExceptionResolver 때문에, 또한 정렬 된 인터페이스를 구현 당신은 당신의 콩 정의에 다음과 같이 뭔가를 할 수 :

<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> 

낮은 순서 값을 가진 콩은 높은 우선 순위를 가지고

(AccessDeniedExceptionResolver 전에 호출이 경우,이 값이 큰 전에 호출됩니다 의미 SimpleMappingEx ceptionResolver.

희망이 도움이되었습니다.

+0

이 작품은 고맙습니다 ... 나는 당신에게 점수를주기 위해 20 시간을 기다려야합니다. – mkoryak

+0

리디렉션에 매핑되는 AccessDeniedException에 대한 SimpleMappingExceptionResolver에 다른 을 추가하는 것이 더 쉽지 않을까요?/login 이렇게하려면 클래스를 구현해야하는 것보다 간단할까요? – digitaljoel

+0

@mkoryak : 고마워요. 그보다 더 나은 해결책이 팝업 될 수도 있습니다. 그렇다면 어려운 느낌은 아닙니다.) 또한 디지털 첼로가 여기서 제안한 것을 살펴보십시오. – esaj

1

또 다른 옵션 : 특정 예외 클래스를 제외시킬 수있는 SimpleMappingExceptionResolver의 하위 클래스를 생성하십시오 (스프링 보안의 경우 기본 처리를 위해 그대로 두십시오).

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[]{}; 
    } 
    } 
} 
관련 문제