2011-08-29 11 views
5

Obecnie próbuję użyć HandlerExceptionResolver do obsługi wyjątków w projekcie Spring MVC.Obsługa wyjątków Spring MVC z HandlerExceptionResolver

Chcę obsługiwać normalne wyjątki za pośrednictwem resolveException, a także 404 za pośrednictwem handleNoSuchRequestHandlingMethod.

W zależności od typu żądania, JSON lub text/html, odpowiedź wyjątku powinna zostać zwrócona.

resolveException działa teraz.

Ale handleNoSuchRequestHandlingMethod daje mi ból głowy. Nigdy nie jest wywoływany!

Według doku metoda powinna być wywoływana 404 błędów

http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/servlet/mvc/support/DefaultHandlerExceptionResolver.html

Co robię źle ...

To, co mam tak daleko.

public class JsonExceptionResolver implements HandlerExceptionResolver { 

    protected final Log logger = LogFactory.getLog(getClass()); 

    public ModelAndView resolveException(HttpServletRequest request, 
    if (exception instanceof NoSuchRequestHandlingMethodException) { 
       return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException)    exception, request, response, handler); 
    } 
    ...     
    } 

    public ModelAndView handleNoSuchRequestHandlingMethod(NoSuchRequestHandlingMethodException ex, 
     HttpServletRequest request, 
     HttpServletResponse response, 
     Object handler){ 

    logger.info("Handle my exception!!!"); 

    ModelAndView mav = new ModelAndView(); 
    boolean isJSON = request.getHeader("Accept").equals("application/json"); 

    if(isJSON){ 
    ... 

    }else{ 
    .. 
    } 

    return mav; 
    } 

} 

EDIT z DefaultHandlerExceptionResolver:

public class MyExceptionResolver extends DefaultHandlerExceptionResolver { 

    protected final Log logger = LogFactory.getLog(getClass()); 

    @Override 
    protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { 
    logger.warn("An Exception has occured in the application", exception); 


    logger.info("exception thrown " + exception.getMessage()); 
    if (exception instanceof NoSuchRequestHandlingMethodException) { 
     return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) exception, request, response, handler); 
    } 

    ... 
    return mav; 
    } 

    public ModelAndView handleNoSuchRequestHandlingMethod(NoSuchRequestHandlingMethodException ex, 
     HttpServletRequest request, 
     HttpServletResponse response, 
     Object handler){ 

    logger.info("Handle my exception!!!"); 

    ModelAndView mav = new ModelAndView(); 
    boolean isJSON = request.getHeader("Accept").equals("application/json"); 

    if(isJSON){ 

     ... 
    }else{ 
     ... 
    } 

    return mav; 
    } 
} 

Powyższy kod nadal nie ma żadnego wpływu.

Jakieś inne pomysły?

Odpowiedz

3

Według Juergena Hoellera ze Springa, nie jest to możliwe z HandlerExceptionResolver, ponieważ działa tylko w podmapowaniu, np.

masz kontroler zmapowany do /account/** i uzyskuje dostęp do metody z konta, w którym nie istnieje mapowanie, takie jak /acount/notExists, niż powinno działać.

będę otworzyć JIRA poprawy bilet dla tej funkcjonalności

EDIT:

JIRA bilet na ten temat

https://jira.springsource.org/browse/SPR-8837?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=72648#comment-72648

2

handleNoSuchRequestHandlingMethod nie jest częścią interfejsu HandlerExceptionResolver, więc samo zadeklarowanie metody o tej nazwie nic nie da. To jest chroniony sposób specyficzny dla DefaultHandlerExceptionResolver, i nazywa się od sposobu jej resolveException (co jest częścią interfejsu):

if (ex instanceof NoSuchRequestHandlingMethodException) { 
    return handleNoSuchRequestHandlingMethod((NoSuchRequestHandlingMethodException) ex, request, response, handler); 
} 

Aby odtworzyć taką samą funkcjonalność, to albo można podklasa DefaultHandlerExceptionResolver i zastąpić metody musisz lub musisz dodać skrzynkę do swojej metody resolveException, która obsługuje NoSuchRequestHandlingMethodException.

+0

zaktualizowałem mój kod. Miałeś to na myśli? –

+1

Próbowałem także z dziedziczeniem z '' DefaultHandlerExceptionResolver'', ale w przypadku 404 '' doResolveException'' nigdy nie zostanie wywołany ... czy nie rozumiałem cię? –